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