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