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 "avcodec_audio_codec_impl.h"
17 #include "i_avcodec_service.h"
18 #include "avcodec_log.h"
19 #include "avcodec_errors.h"
20 #include "avcodec_trace.h"
21 #include "avcodec_codec_name.h"
22 #include "codec_server.h"
23 
24 namespace {
25 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_AUDIO, "AVCodecAudioCodecImpl"};
26 constexpr int32_t DEFAULT_BUFFER_NUM = 4;
27 constexpr const char *INPUT_BUFFER_QUEUE_NAME = "AVCodecAudioCodecImpl";
28 const std::string_view ASYNC_HANDLE_INPUT = "OS_ACodecIn";
29 const std::string_view ASYNC_OUTPUT_FRAME = "OS_ACodecOut";
30 constexpr uint8_t LOGD_FREQUENCY = 5;
31 constexpr uint8_t TIME_OUT_MS = 50;
32 constexpr uint32_t DEFAULT_TRY_DECODE_TIME = 1000;
33 constexpr uint32_t MAX_INDEX = 1000000000;
34 constexpr int64_t MILLISECONDS = 100;
35 } // namespace
36 
37 namespace OHOS {
38 namespace MediaAVCodec {
39 
AudioCodecConsumerListener(AVCodecAudioCodecImpl * impl)40 AudioCodecConsumerListener::AudioCodecConsumerListener(AVCodecAudioCodecImpl *impl)
41 {
42     impl_ = impl;
43 }
44 
OnBufferAvailable()45 void AudioCodecConsumerListener::OnBufferAvailable()
46 {
47     impl_->Notify();
48 }
49 
Init(AVCodecType type,bool isMimeType,const std::string & name)50 int32_t AVCodecAudioCodecImpl::Init(AVCodecType type, bool isMimeType, const std::string &name)
51 {
52     AVCODEC_SYNC_TRACE;
53     Format format;
54     codecService_ = CodecServer::Create();
55     CHECK_AND_RETURN_RET_LOG(codecService_ != nullptr, AVCS_ERR_UNKNOWN, "failed to create codec service");
56 
57     implBufferQueue_ = Media::AVBufferQueue::Create(DEFAULT_BUFFER_NUM, Media::MemoryType::SHARED_MEMORY,
58         INPUT_BUFFER_QUEUE_NAME);
59     CHECK_AND_RETURN_RET_LOG(implBufferQueue_ != nullptr, AVCS_ERR_NO_MEMORY, "failed to create buffer queue");
60 
61     inputTask_ = std::make_unique<TaskThread>(ASYNC_HANDLE_INPUT);
62     CHECK_AND_RETURN_RET_LOG(inputTask_ != nullptr, AVCS_ERR_NO_MEMORY, "failed to create input task");
63     outputTask_ = std::make_unique<TaskThread>(ASYNC_OUTPUT_FRAME);
64     CHECK_AND_RETURN_RET_LOG(outputTask_ != nullptr, AVCS_ERR_NO_MEMORY, "failed to create output task");
65 
66     return codecService_->Init(type, isMimeType, name, *format.GetMeta(), API_VERSION::API_VERSION_11);
67 }
68 
AVCodecAudioCodecImpl()69 AVCodecAudioCodecImpl::AVCodecAudioCodecImpl()
70 {
71     AVCODEC_LOGI("AVCodecAudioCodecImpl:0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
72 }
73 
~AVCodecAudioCodecImpl()74 AVCodecAudioCodecImpl::~AVCodecAudioCodecImpl()
75 {
76     codecService_ = nullptr;
77     AVCODEC_LOGI("AVCodecAudioCodecImpl:0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
78 }
79 
Configure(const Format & format)80 int32_t AVCodecAudioCodecImpl::Configure(const Format &format)
81 {
82     AVCODEC_SYNC_TRACE;
83     CHECK_AND_RETURN_RET_LOG(codecService_ != nullptr, AVCS_ERR_INVALID_STATE, "service died");
84     auto meta = const_cast<Format &>(format).GetMeta();
85     inputBufferSize_ = 0;
86     return codecService_->Configure(meta);
87 }
88 
Prepare()89 int32_t AVCodecAudioCodecImpl::Prepare()
90 {
91     AVCODEC_SYNC_TRACE;
92     CHECK_AND_RETURN_RET_LOG(codecService_ != nullptr, AVCS_ERR_INVALID_STATE, "service died");
93 
94     implProducer_ = implBufferQueue_->GetProducer();
95     codecService_->SetOutputBufferQueue(implProducer_);
96     int32_t ret = codecService_->Prepare();
97     CHECK_AND_RETURN_RET_LOG_LIMIT(ret != AVCS_ERR_TRY_AGAIN, AVCS_ERR_OK,
98         LOGD_FREQUENCY, "no need prepare");
99     CHECK_AND_RETURN_RET_LOG(ret == 0, AVCS_ERR_INVALID_STATE, "prepare fail, ret:%{public}d", ret);
100 
101     implConsumer_ = implBufferQueue_->GetConsumer();
102     mediaCodecProducer_ = codecService_->GetInputBufferQueue();
103     CHECK_AND_RETURN_RET_LOG(mediaCodecProducer_ != nullptr, AVCS_ERR_INVALID_VAL, "mediaCodecProducer_ is nullptr");
104 
105     sptr<Media::IConsumerListener> comsumerListener = new AudioCodecConsumerListener(this);
106     implConsumer_->SetBufferAvailableListener(comsumerListener);
107 
108     outputTask_->RegisterHandler([this] { ConsumerOutputBuffer(); });
109     inputTask_->RegisterHandler([this] { ProduceInputBuffer(); });
110     return AVCS_ERR_OK;
111 }
112 
Start()113 int32_t AVCodecAudioCodecImpl::Start()
114 {
115     AVCODEC_SYNC_TRACE;
116     CHECK_AND_RETURN_RET_LOG(Prepare() == AVCS_ERR_OK, AVCS_ERR_INVALID_STATE, "Prepare failed");
117     CHECK_AND_RETURN_RET_LOG(codecService_ != nullptr, AVCS_ERR_INVALID_STATE, "service died");
118     int32_t ret = codecService_->Start();
119     CHECK_AND_RETURN_RET_LOG(ret == 0, ret, "Start failed, ret:%{public}d", ret);
120     isRunning_ = true;
121     indexInput_ = 0;
122     indexOutput_ = 0;
123     if (inputTask_) {
124         inputTask_->Start();
125     } else {
126         AVCODEC_LOGE("Start failed, inputTask_ is nullptr, please check the inputTask_.");
127         ret = AVCS_ERR_UNKNOWN;
128     }
129     if (outputTask_) {
130         outputTask_->Start();
131     } else {
132         AVCODEC_LOGE("Start failed, outputTask_ is nullptr, please check the outputTask_.");
133         ret = AVCS_ERR_UNKNOWN;
134     }
135     AVCODEC_LOGI("Instances:0x%{public}06" PRIXPTR " Start, ret = %{public}d", FAKE_POINTER(this), ret);
136     return ret;
137 }
138 
Stop()139 int32_t AVCodecAudioCodecImpl::Stop()
140 {
141     AVCODEC_SYNC_TRACE;
142     AVCODEC_LOGI("Instances:0x%{public}06" PRIXPTR " Stop", FAKE_POINTER(this));
143     CHECK_AND_RETURN_RET_LOG(codecService_ != nullptr, AVCS_ERR_INVALID_STATE, "service died");
144     StopTaskAsync();
145     int32_t ret = codecService_->Stop();
146     StopTask();
147     ClearCache();
148     ReturnInputBuffer();
149     return ret;
150 }
151 
Flush()152 int32_t AVCodecAudioCodecImpl::Flush()
153 {
154     AVCODEC_SYNC_TRACE;
155     CHECK_AND_RETURN_RET_LOG(codecService_ != nullptr, AVCS_ERR_INVALID_STATE, "service died");
156     PauseTaskAsync();
157     int32_t ret = codecService_->Flush();
158     PauseTask();
159     ClearCache();
160     ReturnInputBuffer();
161     return ret;
162 }
163 
Reset()164 int32_t AVCodecAudioCodecImpl::Reset()
165 {
166     AVCODEC_SYNC_TRACE;
167     AVCODEC_LOGI("Instances:0x%{public}06" PRIXPTR " Reset", FAKE_POINTER(this));
168     CHECK_AND_RETURN_RET_LOG(codecService_ != nullptr, AVCS_ERR_INVALID_STATE, "service died");
169     StopTaskAsync();
170     int32_t ret = codecService_->Reset();
171     StopTask();
172     ClearCache();
173     ClearInputBuffer();
174     inputBufferSize_ = 0;
175     return ret;
176 }
177 
Release()178 int32_t AVCodecAudioCodecImpl::Release()
179 {
180     AVCODEC_SYNC_TRACE;
181     AVCODEC_LOGI("Instances:0x%{public}06" PRIXPTR " Release", FAKE_POINTER(this));
182     CHECK_AND_RETURN_RET_LOG(codecService_ != nullptr, AVCS_ERR_INVALID_STATE, "service died");
183     StopTaskAsync();
184     int32_t ret = codecService_->Release();
185     StopTask();
186     ClearCache();
187     ClearInputBuffer();
188     inputBufferSize_ = 0;
189     return ret;
190 }
191 
QueueInputBuffer(uint32_t index)192 int32_t AVCodecAudioCodecImpl::QueueInputBuffer(uint32_t index)
193 {
194     AVCODEC_SYNC_TRACE;
195     CHECK_AND_RETURN_RET_LOG(codecService_ != nullptr, AVCS_ERR_INVALID_STATE, "service died");
196     CHECK_AND_RETURN_RET_LOG(mediaCodecProducer_ != nullptr, AVCS_ERR_INVALID_STATE,
197                              "mediaCodecProducer_ is nullptr");
198     CHECK_AND_RETURN_RET_LOG(codecService_->CheckRunning(), AVCS_ERR_INVALID_STATE, "CheckRunning is not running");
199     std::shared_ptr<AVBuffer> buffer;
200     {
201         std::unique_lock lock(inputMutex_);
202         auto it = inputBufferObjMap_.find(index);
203         CHECK_AND_RETURN_RET_LOG(it != inputBufferObjMap_.end(), AVCS_ERR_INVALID_VAL,
204             "Index does not exist");
205         buffer = it->second;
206         inputBufferObjMap_.erase(index);
207     }
208     CHECK_AND_RETURN_RET_LOG(buffer != nullptr, AVCS_ERR_INVALID_STATE, "buffer not found");
209     if (!(buffer->flag_ & AVCODEC_BUFFER_FLAG_EOS) && buffer->GetConfig().size <= 0) {
210         AVCODEC_LOGE("buffer size is 0,please fill audio buffer in");
211         return AVCS_ERR_UNKNOWN;
212     }
213     {
214         std::unique_lock lock(outputMutex_2);
215         inputIndexQueue.emplace(buffer);
216     }
217     outputCondition_.notify_one();
218     return AVCS_ERR_OK;
219 }
220 
221 #ifdef SUPPORT_DRM
SetAudioDecryptionConfig(const sptr<DrmStandard::IMediaKeySessionService> & keySession,const bool svpFlag)222 int32_t AVCodecAudioCodecImpl::SetAudioDecryptionConfig(const sptr<DrmStandard::IMediaKeySessionService> &keySession,
223     const bool svpFlag)
224 {
225     AVCODEC_SYNC_TRACE;
226     CHECK_AND_RETURN_RET_LOG(codecService_ != nullptr, AVCS_ERR_INVALID_STATE, "service died");
227     return codecService_->SetAudioDecryptionConfig(keySession, svpFlag);
228 }
229 #else
SetAudioDecryptionConfig(const sptr<DrmStandard::IMediaKeySessionService> & keySession,const bool svpFlag)230 int32_t AVCodecAudioCodecImpl::SetAudioDecryptionConfig(const sptr<DrmStandard::IMediaKeySessionService> &keySession,
231     const bool svpFlag)
232 {
233     (void)keySession;
234     (void)svpFlag;
235     return 0;
236 }
237 #endif
238 
GetOutputFormat(Format & format)239 int32_t AVCodecAudioCodecImpl::GetOutputFormat(Format &format)
240 {
241     AVCODEC_SYNC_TRACE;
242     CHECK_AND_RETURN_RET_LOG(codecService_ != nullptr, AVCS_ERR_INVALID_STATE, "service died");
243     std::shared_ptr<Media::Meta> parameter = std::make_shared<Media::Meta>();
244     int32_t ret = codecService_->GetOutputFormat(parameter);
245     CHECK_AND_RETURN_RET_LOG(ret == 0, ret, "GetOutputFormat fail, ret:%{public}d", ret);
246     format.SetMeta(parameter);
247     return ret;
248 }
249 
ReleaseOutputBuffer(uint32_t index)250 int32_t AVCodecAudioCodecImpl::ReleaseOutputBuffer(uint32_t index)
251 {
252     AVCODEC_SYNC_TRACE;
253     CHECK_AND_RETURN_RET_LOG(codecService_ != nullptr, AVCS_ERR_INVALID_STATE, "service died");
254     std::shared_ptr<AVBuffer> buffer;
255     {
256         std::unique_lock lock(outputMutex_);
257         auto it = outputBufferObjMap_.find(index);
258         CHECK_AND_RETURN_RET_LOG(it != outputBufferObjMap_.end(), AVCS_ERR_INVALID_VAL,
259             "Index does not exist");
260         buffer = it->second;
261         outputBufferObjMap_.erase(index);
262     }
263     CHECK_AND_RETURN_RET_LOG(buffer != nullptr, AVCS_ERR_INVALID_STATE, "buffer is nullptr");
264     if (buffer->flag_ == AVCODEC_BUFFER_FLAG_EOS) {
265         AVCODEC_LOGI("EOS detected, QueueInputBuffer set eos status.");
266         codecService_->NotifyEos();
267     }
268 
269     Media::Status ret = implConsumer_->ReleaseBuffer(buffer);
270     return StatusToAVCodecServiceErrCode(ret);
271 }
272 
SetParameter(const Format & format)273 int32_t AVCodecAudioCodecImpl::SetParameter(const Format &format)
274 {
275     AVCODEC_SYNC_TRACE;
276     CHECK_AND_RETURN_RET_LOG(codecService_ != nullptr, AVCS_ERR_INVALID_STATE, "service died");
277     auto meta = const_cast<Format &>(format).GetMeta();
278     inputBufferSize_ = 0;
279     return codecService_->SetParameter(meta);
280 }
281 
SetCallback(const std::shared_ptr<MediaCodecCallback> & callback)282 int32_t AVCodecAudioCodecImpl::SetCallback(const std::shared_ptr<MediaCodecCallback> &callback)
283 {
284     AVCODEC_SYNC_TRACE;
285     CHECK_AND_RETURN_RET_LOG(codecService_ != nullptr, AVCS_ERR_INVALID_STATE, "service died");
286     CHECK_AND_RETURN_RET_LOG(callback != nullptr, AVCS_ERR_INVALID_VAL, "callback is nullptr");
287     callback_ = callback;
288     std::shared_ptr<AVCodecInnerCallback> innerCallback = std::make_shared<AVCodecInnerCallback>(this);
289     return codecService_->SetCallback(innerCallback);
290 }
291 
Notify()292 void AVCodecAudioCodecImpl::Notify()
293 {
294     bufferConsumerAvailableCount_++;
295 	// The medicCodec has filled the buffer with the output data in this producer.
296 	// Notify the ProduceInputBuffer thread that it can continue fetching data from the user.
297     inputCondition_.notify_one();
298     outputCondition_.notify_one();
299 }
300 
GetInputBufferSize()301 int32_t AVCodecAudioCodecImpl::GetInputBufferSize()
302 {
303     if (inputBufferSize_ > 0) {
304         return inputBufferSize_;
305     }
306     int32_t capacity = 0;
307     CHECK_AND_RETURN_RET_LOG(codecService_ != nullptr, capacity, "codecService_ is nullptr");
308     std::shared_ptr<Media::Meta> bufferConfig = std::make_shared<Media::Meta>();
309     CHECK_AND_RETURN_RET_LOG(bufferConfig != nullptr, capacity, "bufferConfig is nullptr");
310     int32_t ret = codecService_->GetOutputFormat(bufferConfig);
311     CHECK_AND_RETURN_RET_LOG(ret == 0, capacity, "GetOutputFormat fail");
312     CHECK_AND_RETURN_RET_LOG(bufferConfig->Get<Media::Tag::AUDIO_MAX_INPUT_SIZE>(capacity), capacity,
313                              "get max input buffer size fail");
314     inputBufferSize_ = capacity;
315     return capacity;
316 }
317 
ProduceInputBuffer()318 void AVCodecAudioCodecImpl::ProduceInputBuffer()
319 {
320     AVCODEC_SYNC_TRACE;
321     AVCODEC_LOGD_LIMIT(LOGD_FREQUENCY, "produceInputBuffer enter");
322     if (!isRunning_) {
323         usleep(DEFAULT_TRY_DECODE_TIME);
324         AVCODEC_LOGE("ProduceInputBuffer isRunning_ false");
325         return;
326     }
327     Media::Status ret = Media::Status::OK;
328     Media::AVBufferConfig avBufferConfig;
329     avBufferConfig.size = GetInputBufferSize();
330     std::unique_lock lock2(inputMutex2_);
331     while (isRunning_) {
332         std::shared_ptr<AVBuffer> emptyBuffer = nullptr;
333         CHECK_AND_CONTINUE_LOG(mediaCodecProducer_ != nullptr, "mediaCodecProducer_ is nullptr");
334         ret = mediaCodecProducer_->RequestBuffer(emptyBuffer, avBufferConfig, TIME_OUT_MS);
335         if (ret != Media::Status::OK) {
336             AVCODEC_LOGD_LIMIT(LOGD_FREQUENCY, "produceInputBuffer RequestBuffer fail, ret=%{public}d", ret);
337             break;
338         }
339         CHECK_AND_CONTINUE_LOG(emptyBuffer != nullptr, "buffer is nullptr");
340         {
341             std::unique_lock lock1(inputMutex_);
342             inputBufferObjMap_[indexInput_] = emptyBuffer;
343         }
344         CHECK_AND_CONTINUE_LOG(callback_ != nullptr, "callback is nullptr");
345         callback_->OnInputBufferAvailable(indexInput_, emptyBuffer);
346         indexInput_ = (indexInput_ >= MAX_INDEX) ? 0 : ++indexInput_;
347     }
348 
349     inputCondition_.wait_for(lock2, std::chrono::milliseconds(MILLISECONDS),
350                              [this] { return ((mediaCodecProducer_->GetQueueSize() > 0) || !isRunning_); });
351     AVCODEC_LOGD_LIMIT(LOGD_FREQUENCY, "produceInputBuffer exit");
352 }
353 
ConsumerOutputBuffer()354 void AVCodecAudioCodecImpl::ConsumerOutputBuffer()
355 {
356     AVCODEC_SYNC_TRACE;
357     AVCODEC_LOGD_LIMIT(LOGD_FREQUENCY, "ConsumerOutputBuffer enter");
358     if (!isRunning_) {
359         usleep(DEFAULT_TRY_DECODE_TIME);
360         AVCODEC_LOGE("Consumer isRunning_ false");
361         return;
362     }
363 
364     while (isRunning_ && (!inputIndexQueue.empty())) {
365         std::shared_ptr<AVBuffer> buffer;
366         {
367             std::unique_lock lock2(outputMutex_2);
368             buffer = inputIndexQueue.front();
369             inputIndexQueue.pop();
370         }
371         Media::Status ret = mediaCodecProducer_->PushBuffer(buffer, true);
372         if (ret != Media::Status::OK) {
373             AVCODEC_LOGW("ConsumerOutputBuffer PushBuffer fail, ret=%{public}d", ret);
374             break;
375         }
376         inputCondition_.notify_all();
377     }
378     std::unique_lock lock2(outputMutex_2);
379     outputCondition_.wait_for(lock2, std::chrono::milliseconds(MILLISECONDS),
380                               [this] { return ((!inputIndexQueue.empty()) || !isRunning_); });
381     AVCODEC_LOGD_LIMIT(LOGD_FREQUENCY, "ConsumerOutputBuffer exit");
382 }
383 
ClearCache()384 void AVCodecAudioCodecImpl::ClearCache()
385 {
386     std::unique_lock lock(outputMutex_);
387     for (auto iter = outputBufferObjMap_.begin(); iter != outputBufferObjMap_.end();) {
388         std::shared_ptr<AVBuffer> buffer;
389         buffer = iter->second;
390         iter = outputBufferObjMap_.erase(iter);
391         implConsumer_->ReleaseBuffer(buffer);
392     }
393 }
394 
ReturnInputBuffer()395 void AVCodecAudioCodecImpl::ReturnInputBuffer()
396 {
397     for (const auto &inputMap : inputBufferObjMap_) {
398         mediaCodecProducer_->PushBuffer(inputMap.second, false);
399     }
400     {
401         std::unique_lock lock(inputMutex_);
402         inputBufferObjMap_.clear();
403     }
404     while (!inputIndexQueue.empty()) {
405         std::shared_ptr<AVBuffer> buffer;
406         {
407             std::unique_lock lock(outputMutex_2);
408             buffer = inputIndexQueue.front();
409             inputIndexQueue.pop();
410         }
411         mediaCodecProducer_->PushBuffer(buffer, false);
412     }
413 }
414 
ClearInputBuffer()415 void AVCodecAudioCodecImpl::ClearInputBuffer()
416 {
417     {
418         std::unique_lock lock(inputMutex_);
419         inputBufferObjMap_.clear();
420     }
421     while (!inputIndexQueue.empty()) {
422         std::unique_lock lock(outputMutex_2);
423         inputIndexQueue.pop();
424     }
425 }
426 
StopTaskAsync()427 void AVCodecAudioCodecImpl::StopTaskAsync()
428 {
429     isRunning_ = false;
430     {
431         std::lock_guard lock(inputMutex2_);
432         inputCondition_.notify_one();
433     }
434     {
435         std::lock_guard lock(outputMutex_2);
436         outputCondition_.notify_one();
437     }
438     if (inputTask_) {
439         inputTask_->StopAsync();
440     }
441     if (outputTask_) {
442         outputTask_->StopAsync();
443     }
444 }
445 
PauseTaskAsync()446 void AVCodecAudioCodecImpl::PauseTaskAsync()
447 {
448     isRunning_ = false;
449     {
450         std::lock_guard lock(inputMutex2_);
451         inputCondition_.notify_one();
452     }
453     {
454         std::lock_guard lock(outputMutex_2);
455         outputCondition_.notify_one();
456     }
457     if (inputTask_) {
458         inputTask_->PauseAsync();
459     }
460     if (outputTask_) {
461         outputTask_->PauseAsync();
462     }
463 }
464 
StopTask()465 void AVCodecAudioCodecImpl::StopTask()
466 {
467     if (inputTask_) {
468         inputTask_->Stop();
469     }
470     if (outputTask_) {
471         outputTask_->Stop();
472     }
473 }
474 
PauseTask()475 void AVCodecAudioCodecImpl::PauseTask()
476 {
477     if (inputTask_) {
478         inputTask_->Pause();
479     }
480     if (outputTask_) {
481         outputTask_->Pause();
482     }
483 }
484 
AVCodecInnerCallback(AVCodecAudioCodecImpl * impl)485 AVCodecAudioCodecImpl::AVCodecInnerCallback::AVCodecInnerCallback(AVCodecAudioCodecImpl *impl) : impl_(impl) {}
486 
OnError(AVCodecErrorType errorType,int32_t errorCode)487 void AVCodecAudioCodecImpl::AVCodecInnerCallback::OnError(AVCodecErrorType errorType, int32_t errorCode)
488 {
489     if (impl_->callback_) {
490         impl_->callback_->OnError(errorType, errorCode);
491     }
492 }
493 
OnOutputFormatChanged(const Format & format)494 void AVCodecAudioCodecImpl::AVCodecInnerCallback::OnOutputFormatChanged(const Format &format)
495 {
496     if (impl_->callback_) {
497         impl_->callback_->OnOutputFormatChanged(format);
498     }
499 }
500 
OnInputBufferAvailable(uint32_t index,std::shared_ptr<AVBuffer> buffer)501 void AVCodecAudioCodecImpl::AVCodecInnerCallback::OnInputBufferAvailable(uint32_t index,
502                                                                          std::shared_ptr<AVBuffer> buffer)
503 {
504     (void)index;
505     (void)buffer;
506 }
507 
OnOutputBufferAvailable(uint32_t index,std::shared_ptr<AVBuffer> buffer)508 void AVCodecAudioCodecImpl::AVCodecInnerCallback::OnOutputBufferAvailable(uint32_t index,
509                                                                           std::shared_ptr<AVBuffer> buffer)
510 {
511     std::shared_ptr<AVBuffer> outputBuffer;
512     if (impl_->callback_) {
513         Media::Status ret = impl_->implConsumer_->AcquireBuffer(outputBuffer);
514         if (ret != Media::Status::OK) {
515             AVCODEC_LOGE("Consumer AcquireBuffer fail,ret=%{public}d", ret);
516             return;
517         }
518         {
519             std::unique_lock lock(impl_->outputMutex_);
520             impl_->outputBufferObjMap_[impl_->indexOutput_] = outputBuffer;
521         }
522         impl_->callback_->OnOutputBufferAvailable(impl_->indexOutput_, outputBuffer);
523         impl_->indexOutput_ = (impl_->indexOutput_ >= MAX_INDEX) ? 0 : ++impl_->indexOutput_;
524     }
525 }
526 } // namespace MediaAVCodec
527 } // namespace OHOS
528