• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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