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