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