• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023-2025 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 #include "avcodec_audio_codec_inner_impl.h"
16 #include "i_avcodec_service.h"
17 #include "avcodec_log.h"
18 #include "avcodec_errors.h"
19 #include "avcodec_trace.h"
20 #include "avcodec_codec_name.h"
21 #include "codec_server.h"
22 #include "drm_i_keysession_service.h"
23 
24 namespace OHOS {
25 namespace MediaAVCodec {
26 namespace {
27 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_AUDIO, "AVCodecAudioCodecInnerImpl"};
28 constexpr size_t DEFAULT_OUTPUT_BUFFER_NUM = 4;
29 }
30 
31 class OutputBufferAvailableListener : public Media::IConsumerListener {
32 public:
OutputBufferAvailableListener(std::shared_ptr<IConsumerListener> consumerListener)33     explicit OutputBufferAvailableListener(std::shared_ptr<IConsumerListener> consumerListener)
34         : consumerListener_(consumerListener)
35     {}
36 
OnBufferAvailable()37     void OnBufferAvailable() override
38     {
39         auto realPtr = consumerListener_.lock();
40         if (realPtr != nullptr) {
41             realPtr->OnBufferAvailable();
42         } else {
43             AVCODEC_LOGW("AVCodecAudioCodecSyncInnerImpl was released, can not callback OnBufferAvailable");
44         }
45     }
46 
47 private:
48     std::weak_ptr<IConsumerListener> consumerListener_;
49 };
50 
CreateByMime(const std::string & mime,bool isEncoder)51 std::shared_ptr<AVCodecAudioCodec> AudioCodecFactory::CreateByMime(const std::string &mime, bool isEncoder)
52 {
53     AVCODEC_SYNC_TRACE;
54     std::shared_ptr<AVCodecAudioCodecInnerImpl> impl = std::make_shared<AVCodecAudioCodecInnerImpl>();
55     AVCodecType type = AVCODEC_TYPE_AUDIO_DECODER;
56     if (isEncoder) {
57         type = AVCODEC_TYPE_AUDIO_ENCODER;
58     }
59     int32_t ret = impl->Init(type, true, mime);
60     CHECK_AND_RETURN_RET_LOG(ret == AVCodecServiceErrCode::AVCS_ERR_OK,
61         nullptr, "failed to init AVCodecAudioCodecInnerImpl");
62     return impl;
63 }
64 
CreateByName(const std::string & name)65 std::shared_ptr<AVCodecAudioCodec> AudioCodecFactory::CreateByName(const std::string &name)
66 {
67     AVCODEC_SYNC_TRACE;
68     std::shared_ptr<AVCodecAudioCodecInnerImpl> impl = std::make_shared<AVCodecAudioCodecInnerImpl>();
69     std::string codecMimeName = name;
70     if (name.compare(AVCodecCodecName::AUDIO_DECODER_API9_AAC_NAME) == 0) {
71         codecMimeName = AVCodecCodecName::AUDIO_DECODER_AAC_NAME;
72     } else if (name.compare(AVCodecCodecName::AUDIO_ENCODER_API9_AAC_NAME) == 0) {
73         codecMimeName = AVCodecCodecName::AUDIO_ENCODER_AAC_NAME;
74     }
75     AVCodecType type = AVCODEC_TYPE_AUDIO_ENCODER;
76     if (codecMimeName.find("Encoder") != codecMimeName.npos) {
77         type = AVCODEC_TYPE_AUDIO_ENCODER;
78     } else {
79         type = AVCODEC_TYPE_AUDIO_DECODER;
80     }
81     int32_t ret = impl->Init(type, false, name);
82     CHECK_AND_RETURN_RET_LOG(ret == AVCodecServiceErrCode::AVCS_ERR_OK,
83         nullptr, "failed to init AVCodecAudioCodecInnerImpl");
84     return impl;
85 }
86 
AVCodecAudioCodecInnerImpl()87 AVCodecAudioCodecInnerImpl::AVCodecAudioCodecInnerImpl()
88 {
89     AVCODEC_LOGD("AVCodecAudioCodecInnerImpl:0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
90 }
91 
~AVCodecAudioCodecInnerImpl()92 AVCodecAudioCodecInnerImpl::~AVCodecAudioCodecInnerImpl()
93 {
94     codecService_ = nullptr;
95     AVCODEC_LOGD("AVCodecAudioCodecInnerImpl:0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
96 }
97 
Init(AVCodecType type,bool isMimeType,const std::string & name)98 int32_t AVCodecAudioCodecInnerImpl::Init(AVCodecType type, bool isMimeType, const std::string &name)
99 {
100     AVCODEC_SYNC_TRACE;
101     AVCODEC_LOGI("AVCodecAudioCodecInnerImpl Init");
102     Format format;
103     codecService_ = CodecServer::Create();
104     CHECK_AND_RETURN_RET_LOG(codecService_ != nullptr, AVCodecServiceErrCode::AVCS_ERR_NO_MEMORY,
105                              "failed to create codec service");
106     int32_t ret = codecService_->Init(type, isMimeType, name, *format.GetMeta(), API_VERSION::API_VERSION_11);
107     return ret;
108 }
109 
Configure(const std::shared_ptr<Media::Meta> & meta)110 int32_t AVCodecAudioCodecInnerImpl::Configure(const std::shared_ptr<Media::Meta> &meta)
111 {
112     AVCODEC_LOGI("AVCodecAudioCodecInnerImpl Configure");
113     CHECK_AND_RETURN_RET_LOG(codecService_ != nullptr, AVCodecServiceErrCode::AVCS_ERR_INVALID_OPERATION,
114                              "service died");
115     bool enableSyncMode = false;
116     meta->GetData(Tag::AV_CODEC_ENABLE_SYNC_MODE, enableSyncMode);
117     if (enableSyncMode) {
118         AVCODEC_LOGI("AVCodecAudioCodecInnerImpl create SyncCodecAdapter");
119         syncCodecAdapter_ = std::make_shared<SyncCodecAdapter>(DEFAULT_OUTPUT_BUFFER_NUM);
120         int32_t ret = codecService_->SetOutputBufferQueue(syncCodecAdapter_->GetProducer());
121         if (ret != static_cast<int32_t>(AVCodecServiceErrCode::AVCS_ERR_OK)) {
122             AVCODEC_LOGW("AVCodecAudioCodecInnerImpl set sync mode set failed, ret %{public}d", ret);
123             syncCodecAdapter_.reset();
124             return ret;
125         }
126     }
127     int32_t ret = codecService_->Configure(meta);
128     return ret;
129 }
130 
SetOutputBufferQueue(const sptr<Media::AVBufferQueueProducer> & bufferQueueProducer)131 int32_t AVCodecAudioCodecInnerImpl::SetOutputBufferQueue(
132     const sptr<Media::AVBufferQueueProducer> &bufferQueueProducer)
133 {
134     AVCODEC_LOGI("AVCodecAudioCodecInnerImpl SetOutputBufferQueue");
135     CHECK_AND_RETURN_RET_LOG(codecService_ != nullptr, AVCodecServiceErrCode::AVCS_ERR_INVALID_OPERATION,
136                              "service died");
137     if (syncCodecAdapter_ != nullptr) {
138         return static_cast<int32_t>(AVCodecServiceErrCode::AVCS_ERR_OK);
139     }
140     int32_t ret = codecService_->SetOutputBufferQueue(bufferQueueProducer);
141     return ret;
142 }
143 
Prepare()144 int32_t AVCodecAudioCodecInnerImpl::Prepare()
145 {
146     AVCODEC_LOGI("AVCodecAudioCodecInnerImpl Prepare");
147     CHECK_AND_RETURN_RET_LOG(codecService_ != nullptr, AVCodecServiceErrCode::AVCS_ERR_INVALID_OPERATION,
148                              "service died");
149     int32_t ret = codecService_->Prepare();
150     if (syncCodecAdapter_ != nullptr && ret == static_cast<int32_t>(AVCodecServiceErrCode::AVCS_ERR_OK)) {
151         ret = syncCodecAdapter_->Prepare(codecService_->GetInputBufferQueue());
152     }
153     return ret;
154 }
155 
GetInputBufferQueue()156 sptr<Media::AVBufferQueueProducer> AVCodecAudioCodecInnerImpl::GetInputBufferQueue()
157 {
158     AVCODEC_LOGI("AVCodecAudioCodecInnerImpl GetInputBufferQueue");
159     CHECK_AND_RETURN_RET_LOG(codecService_ != nullptr, nullptr,
160                              "service died");
161     return codecService_->GetInputBufferQueue();
162 }
163 
GetInputBufferQueueConsumer()164 sptr<Media::AVBufferQueueConsumer> AVCodecAudioCodecInnerImpl::GetInputBufferQueueConsumer()
165 {
166     AVCODEC_LOGD("AVCodecAudioCodecInnerImpl GetInputBufferQueueConsumer");
167     CHECK_AND_RETURN_RET_LOG(codecService_ != nullptr, nullptr, "GetInputBufferQueueConsumer service died");
168     return codecService_->GetInputBufferQueueConsumer();
169 }
170 
GetOutputBufferQueueProducer()171 sptr<Media::AVBufferQueueProducer> AVCodecAudioCodecInnerImpl::GetOutputBufferQueueProducer()
172 {
173     AVCODEC_LOGD("AVCodecAudioCodecInnerImpl GetOutputBufferQueueProducer");
174     CHECK_AND_RETURN_RET_LOG(codecService_ != nullptr, nullptr, "GetOutputBufferQueueProducer service died");
175     return codecService_->GetOutputBufferQueueProducer();
176 }
177 
ProcessInputBufferInner(bool isTriggeredByOutPort,bool isFlushed,uint32_t & bufferStatus)178 void AVCodecAudioCodecInnerImpl::ProcessInputBufferInner(bool isTriggeredByOutPort, bool isFlushed,
179     uint32_t &bufferStatus)
180 {
181     AVCODEC_LOGD("AVCodecAudioCodecInnerImpl ProcessInputBufferInner");
182     CHECK_AND_RETURN_LOG(codecService_ != nullptr, "ProcessInputBufferInner service died");
183     codecService_->ProcessInputBufferInner(isTriggeredByOutPort, isFlushed, bufferStatus);
184 }
185 
Start()186 int32_t AVCodecAudioCodecInnerImpl::Start()
187 {
188     AVCODEC_LOGI("AVCodecAudioCodecInnerImpl Start");
189     CHECK_AND_RETURN_RET_LOG(codecService_ != nullptr, AVCodecServiceErrCode::AVCS_ERR_INVALID_OPERATION,
190                              "service died");
191     int32_t ret = codecService_->Start();
192     return ret;
193 }
194 
Stop()195 int32_t AVCodecAudioCodecInnerImpl::Stop()
196 {
197     AVCODEC_LOGI("AVCodecAudioCodecInnerImpl Stop");
198     CHECK_AND_RETURN_RET_LOG(codecService_ != nullptr, AVCodecServiceErrCode::AVCS_ERR_INVALID_OPERATION,
199                              "service died");
200     int32_t ret = codecService_->Stop();
201     return ret;
202 }
203 
Flush()204 int32_t AVCodecAudioCodecInnerImpl::Flush()
205 {
206     AVCODEC_LOGI("AVCodecAudioCodecInnerImpl Flush");
207     CHECK_AND_RETURN_RET_LOG(codecService_ != nullptr, AVCodecServiceErrCode::AVCS_ERR_INVALID_OPERATION,
208                              "service died");
209     int32_t ret = codecService_->Flush();
210     return ret;
211 }
212 
Reset()213 int32_t AVCodecAudioCodecInnerImpl::Reset()
214 {
215     AVCODEC_LOGI("AVCodecAudioCodecInnerImpl Reset");
216     CHECK_AND_RETURN_RET_LOG(codecService_ != nullptr, AVCodecServiceErrCode::AVCS_ERR_INVALID_OPERATION,
217                              "service died");
218     int32_t ret = codecService_->Reset();
219     return ret;
220 }
221 
Release()222 int32_t AVCodecAudioCodecInnerImpl::Release()
223 {
224     AVCODEC_LOGI("AVCodecAudioCodecInnerImpl Release");
225     CHECK_AND_RETURN_RET_LOG(codecService_ != nullptr, AVCodecServiceErrCode::AVCS_ERR_INVALID_OPERATION,
226                              "service died");
227     int32_t ret = codecService_->Release();
228     return ret;
229 }
230 
NotifyEos()231 int32_t AVCodecAudioCodecInnerImpl::NotifyEos()
232 {
233     AVCODEC_LOGI("AVCodecAudioCodecInnerImpl NotifyEos");
234     CHECK_AND_RETURN_RET_LOG(codecService_ != nullptr, AVCodecServiceErrCode::AVCS_ERR_INVALID_OPERATION,
235                              "service died");
236     int32_t ret = codecService_->NotifyEos();
237     return ret;
238 }
239 
SetParameter(const std::shared_ptr<Media::Meta> & parameter)240 int32_t AVCodecAudioCodecInnerImpl::SetParameter(const std::shared_ptr<Media::Meta> &parameter)
241 {
242     AVCODEC_LOGI("AVCodecAudioCodecInnerImpl SetParameter");
243     CHECK_AND_RETURN_RET_LOG(codecService_ != nullptr, AVCodecServiceErrCode::AVCS_ERR_INVALID_OPERATION,
244                              "service died");
245     int32_t ret = codecService_->SetParameter(parameter);
246     return ret;
247 }
248 
GetOutputFormat(std::shared_ptr<Media::Meta> & parameter)249 int32_t AVCodecAudioCodecInnerImpl::GetOutputFormat(std::shared_ptr<Media::Meta> &parameter)
250 {
251     AVCODEC_LOGD_LIMIT(10, "AVCodecAudioCodecInnerImpl GetOutputFormat");   // limit10
252     CHECK_AND_RETURN_RET_LOG(codecService_ != nullptr, AVCodecServiceErrCode::AVCS_ERR_INVALID_OPERATION,
253                              "service died");
254     int32_t ret = codecService_->GetOutputFormat(parameter);
255     return ret;
256 }
257 
ChangePlugin(const std::string & mime,bool isEncoder,const std::shared_ptr<Media::Meta> & meta)258 int32_t AVCodecAudioCodecInnerImpl::ChangePlugin(
259     const std::string &mime, bool isEncoder, const std::shared_ptr<Media::Meta> &meta)
260 {
261     AVCODEC_LOGD("AVCodecAudioCodecInnerImpl ChangePlugin");
262     CHECK_AND_RETURN_RET_LOG(
263         codecService_ != nullptr, AVCodecServiceErrCode::AVCS_ERR_INVALID_OPERATION, "service died");
264     return codecService_->ChangePlugin(mime, isEncoder, meta);
265 }
266 
SetCodecCallback(const std::shared_ptr<MediaCodecCallback> & codecCallback)267 int32_t AVCodecAudioCodecInnerImpl::SetCodecCallback(const std::shared_ptr<MediaCodecCallback> &codecCallback)
268 {
269     AVCODEC_LOGD("AVCodecAudioCodecInnerImpl SetCodecCallback");
270     CHECK_AND_RETURN_RET_LOG(
271         codecService_ != nullptr, AVCodecServiceErrCode::AVCS_ERR_INVALID_OPERATION, "service died");
272     return codecService_->SetCodecCallback(codecCallback);
273 }
274 
SetAudioDecryptionConfig(const sptr<DrmStandard::IMediaKeySessionService> & keySession,const bool svpFlag)275 int32_t AVCodecAudioCodecInnerImpl::SetAudioDecryptionConfig(
276     const sptr<DrmStandard::IMediaKeySessionService> &keySession, const bool svpFlag)
277 {
278     AVCODEC_LOGD("AVCodecAudioCodecInnerImpl SetAudioDecryptionConfig");
279     CHECK_AND_RETURN_RET_LOG(
280         codecService_ != nullptr, AVCodecServiceErrCode::AVCS_ERR_INVALID_OPERATION, "service died");
281     return codecService_->SetAudioDecryptionConfig(keySession, svpFlag);
282 }
283 
SetDumpInfo(bool isDump,uint64_t instanceId)284 void AVCodecAudioCodecInnerImpl::SetDumpInfo(bool isDump, uint64_t instanceId)
285 {
286     AVCODEC_LOGD("AVCodecAudioCodecInnerImpl SetDumpInfo");
287     CHECK_AND_RETURN_LOG(codecService_ != nullptr, "service died");
288     return codecService_->SetDumpInfo(isDump, instanceId);
289 }
290 
ProcessInputBuffer()291 void AVCodecAudioCodecInnerImpl::ProcessInputBuffer()
292 {
293     AVCODEC_LOGD("AVCodecAudioCodecInnerImpl ProcessInputBuffer");
294     CHECK_AND_RETURN_LOG(codecService_ != nullptr, "service died");
295     codecService_->ProcessInputBuffer();
296 }
297 
QueryInputBuffer(uint32_t * index,int32_t bufferSize,int64_t timeoutUs)298 int32_t AVCodecAudioCodecInnerImpl::QueryInputBuffer(uint32_t *index, int32_t bufferSize, int64_t timeoutUs)
299 {
300     return syncCodecAdapter_ != nullptr ? syncCodecAdapter_->QueryInputBuffer(index, bufferSize, timeoutUs)
301                                         : AVCodecServiceErrCode::AVCS_ERR_INVALID_VAL;
302 }
303 
GetInputBuffer(uint32_t index)304 std::shared_ptr<AVBuffer> AVCodecAudioCodecInnerImpl::GetInputBuffer(uint32_t index)
305 {
306     return syncCodecAdapter_ != nullptr ? syncCodecAdapter_->GetInputBuffer(index) : nullptr;
307 }
308 
GetOutputBuffer(int64_t timeoutUs)309 std::shared_ptr<AVBuffer> AVCodecAudioCodecInnerImpl::GetOutputBuffer(int64_t timeoutUs)
310 {
311     return syncCodecAdapter_ != nullptr ? syncCodecAdapter_->GetOutputBuffer(timeoutUs) : nullptr;
312 }
313 
PushInputBuffer(uint32_t index,bool available)314 int32_t AVCodecAudioCodecInnerImpl::PushInputBuffer(uint32_t index, bool available)
315 {
316     return syncCodecAdapter_ != nullptr ? syncCodecAdapter_->PushInputBuffer(index, available)
317                                         : AVCodecServiceErrCode::AVCS_ERR_INVALID_VAL;
318 }
319 
ReleaseOutputBuffer(const std::shared_ptr<AVBuffer> & buffer)320 int32_t AVCodecAudioCodecInnerImpl::ReleaseOutputBuffer(const std::shared_ptr<AVBuffer> &buffer)
321 {
322     return syncCodecAdapter_ != nullptr ? syncCodecAdapter_->ReleaseOutputBuffer(buffer)
323                                         : AVCodecServiceErrCode::AVCS_ERR_INVALID_VAL;
324 }
325 
SyncCodecAdapter(size_t outputBufferSize)326 AVCodecAudioCodecInnerImpl::SyncCodecAdapter::SyncCodecAdapter(size_t outputBufferSize)
327     : init_(false), inputIndex_(0), outputAvaliableNum_(0)
328 {
329     AVCODEC_LOGI("SyncCodecAdapter Create, outputBufferSize %zu", outputBufferSize);
330 
331     innerBufferQueue_ = Media::AVBufferQueue::Create(
332         outputBufferSize, Media::MemoryType::SHARED_MEMORY, "AVCodecAudioCodecSyncInnerImpl");
333     if (innerBufferQueue_ != nullptr) {
334         bufferQueueConsumer_ = innerBufferQueue_->GetConsumer();
335     } else {
336         AVCODEC_LOGE("SyncCodecAdapter Create innerBufferQueue failed");
337     }
338 }
339 
~SyncCodecAdapter()340 AVCodecAudioCodecInnerImpl::SyncCodecAdapter::~SyncCodecAdapter()
341 {
342     AVCODEC_LOGI("~SyncCodecAdapter");
343     int32_t index = 0;
344     if (bufferQueueProducer_ != nullptr) {
345         for (auto &it : inputBuffers_) {
346             if (it == nullptr) {
347                 continue;
348             }
349             Status ret = bufferQueueProducer_->PushBuffer(it, false);
350             if (ret != Status::OK) {
351                 AVCODEC_LOGE("~SyncCodecAdapter release inputBuffer %{public}d failed, ret = %{public}d", index, ret);
352             }
353             ++index;
354         }
355     }
356     inputBuffers_.clear();
357 
358     index = 0;
359     if (bufferQueueConsumer_ != nullptr) {
360         for (auto &it : outputBuffers_) {
361             Status ret = bufferQueueConsumer_->ReleaseBuffer(it.second);
362             if (ret != Status::OK) {
363                 AVCODEC_LOGE("~SyncCodecAdapter release outputBuffer %{public}d failed, ret = %{public}d", index, ret);
364             }
365             ++index;
366         }
367     }
368     outputBuffers_.clear();
369 }
370 
Prepare(const sptr<Media::AVBufferQueueProducer> & bufferQueueProducer)371 int32_t AVCodecAudioCodecInnerImpl::SyncCodecAdapter::Prepare(
372     const sptr<Media::AVBufferQueueProducer> &bufferQueueProducer)
373 {
374     AVCODEC_LOGI("SyncCodecAdapter Prepare, init %{public}d", static_cast<int32_t>(init_));
375 
376     if (!init_) {
377         if (bufferQueueConsumer_ != nullptr && bufferQueueProducer != nullptr) {
378             bufferQueueProducer_ = bufferQueueProducer;
379             inputBuffers_.resize(bufferQueueProducer_->GetQueueSize());
380 
381             sptr<IConsumerListener> listener = new OutputBufferAvailableListener(shared_from_this());
382             Status ret = bufferQueueConsumer_->SetBufferAvailableListener(listener);
383             if (ret != Status::OK) {
384                 AVCODEC_LOGE(
385                     "SyncCodecAdapter SetBufferAvailableListener failed, ret %{public}d", static_cast<int32_t>(ret));
386                 return StatusToAVCodecServiceErrCode(ret);
387             }
388 
389             init_ = true;
390         } else {
391             AVCODEC_LOGE("SyncCodecAdapter Prepare failed, init %{public}d, bufferQueueConsumer %{public}d, "
392                          "bufferQueueProducer %{public}d",
393                 static_cast<int32_t>(init_),
394                 static_cast<int32_t>(bufferQueueConsumer_ != nullptr),
395                 static_cast<int32_t>(bufferQueueProducer_ != nullptr));
396             return AVCodecServiceErrCode::AVCS_ERR_UNKNOWN;
397         }
398     }
399     return AVCodecServiceErrCode::AVCS_ERR_OK;
400 }
401 
QueryInputBuffer(uint32_t * index,int32_t bufferSize,int64_t timeoutUs)402 int32_t AVCodecAudioCodecInnerImpl::SyncCodecAdapter::QueryInputBuffer(
403     uint32_t *index, int32_t bufferSize, int64_t timeoutUs)
404 {
405     if (!init_) {
406         AVCODEC_LOGW("SyncCodecAdapter QueryInputBuffer do not work before prepare");
407         return AVCodecServiceErrCode::AVCS_ERR_INVALID_STATE;
408     }
409 
410     if (index == nullptr) {
411         AVCODEC_LOGW("SyncCodecAdapter QueryInputBuffer failed, input indexPtr is nullptr");
412         return AVCodecServiceErrCode::AVCS_ERR_INPUT_DATA_ERROR;
413     }
414 
415     avBufferConfig_.size = bufferSize;
416     Status ret = bufferQueueProducer_->RequestBufferWaitUs(inputBuffers_[inputIndex_], avBufferConfig_, timeoutUs);
417     if (ret != Status::OK) {
418         AVCODEC_LOGE("SyncCodecAdapter RequestBuffer failed, index %{public}u is invaild", *index);
419         return StatusToAVCodecServiceErrCode(ret);
420     }
421 
422     *index = inputIndex_;
423     if (++inputIndex_ >= inputBuffers_.size()) {
424         inputIndex_ = 0;
425     }
426 
427     return AVCodecServiceErrCode::AVCS_ERR_OK;
428 }
429 
GetInputBuffer(uint32_t index)430 std::shared_ptr<AVBuffer> AVCodecAudioCodecInnerImpl::SyncCodecAdapter::GetInputBuffer(uint32_t index)
431 {
432     if (index >= inputBuffers_.size() || inputBuffers_[index] == nullptr) {
433         AVCODEC_LOGD("SyncCodecAdapter GetInputBuffer failed, index %{public}u is invaild", index);
434         return nullptr;
435     }
436 
437     return inputBuffers_[index];
438 }
439 
GetOutputBuffer(int64_t timeoutUs)440 std::shared_ptr<AVBuffer> AVCodecAudioCodecInnerImpl::SyncCodecAdapter::GetOutputBuffer(int64_t timeoutUs)
441 {
442     if (!init_) {
443         AVCODEC_LOGW("SyncCodecAdapter GetOutputBuffer do not work before prepare");
444         return nullptr;
445     }
446 
447     std::shared_ptr<AVBuffer> outputBuffer;
448     std::unique_lock<std::mutex> lock(outputMutex_);
449 
450     if (outputAvaliableNum_ == 0) {
451         if (!WaitFor(lock, timeoutUs)) {
452             return nullptr;
453         }
454     }
455 
456     Status ret = bufferQueueConsumer_->AcquireBuffer(outputBuffer);
457     --outputAvaliableNum_;
458 
459     if (ret != Status::OK) {
460         AVCODEC_LOGE(
461             "AVCodecAudioCodecSyncInnerImpl Consumer AcquireBuffer fail, ret= %{public}d", static_cast<int32_t>(ret));
462         return nullptr;
463     }
464 
465     if (outputBuffer == nullptr) {
466         AVCODEC_LOGE("AVCodecAudioCodecSyncInnerImpl outputBuffer is nullptr");
467         return nullptr;
468     }
469     outputBuffers_.emplace(std::make_pair(outputBuffer.get(), outputBuffer));
470 
471     return outputBuffer;
472 }
473 
PushInputBuffer(uint32_t index,bool available)474 int32_t AVCodecAudioCodecInnerImpl::SyncCodecAdapter::PushInputBuffer(uint32_t index, bool available)
475 {
476     if (!init_) {
477         AVCODEC_LOGW("SyncCodecAdapter PushInputBuffer do not work before prepare");
478         return AVCodecServiceErrCode::AVCS_ERR_INVALID_STATE;
479     }
480 
481     if (index >= inputBuffers_.size() || inputBuffers_[index] == nullptr) {
482         return AVCodecServiceErrCode::AVCS_ERR_INPUT_DATA_ERROR;
483     }
484 
485     Status ret = bufferQueueProducer_->PushBuffer(inputBuffers_[index], available);
486     if (ret != Status::OK) {
487         AVCODEC_LOGE("SyncCodecAdapter PushInputBuffer failed, ret = %{public}d", ret);
488     }
489     inputBuffers_[index].reset();
490     return StatusToAVCodecServiceErrCode(ret);
491 }
492 
ReleaseOutputBuffer(const std::shared_ptr<AVBuffer> & buffer)493 int32_t AVCodecAudioCodecInnerImpl::SyncCodecAdapter::ReleaseOutputBuffer(const std::shared_ptr<AVBuffer> &buffer)
494 {
495     if (!init_) {
496         AVCODEC_LOGW("SyncCodecAdapter ReleaseOutputBuffer do not work before prepare");
497         return AVCodecServiceErrCode::AVCS_ERR_INVALID_STATE;
498     }
499 
500     {
501         std::unique_lock<std::mutex> lock(outputMutex_);
502         auto it = outputBuffers_.find(buffer.get());
503         if (it == outputBuffers_.end()) {
504             return AVCodecServiceErrCode::AVCS_ERR_INPUT_DATA_ERROR;
505         }
506         outputBuffers_.erase(it);
507     }
508 
509     return StatusToAVCodecServiceErrCode(bufferQueueConsumer_->ReleaseBuffer(buffer));
510 }
511 
OnBufferAvailable()512 void AVCodecAudioCodecInnerImpl::SyncCodecAdapter::OnBufferAvailable()
513 {
514     {
515         std::unique_lock<std::mutex> lock(outputMutex_);
516         ++outputAvaliableNum_;
517     }
518     outputCV_.notify_all();
519 }
520 
GetProducer()521 sptr<Media::AVBufferQueueProducer> AVCodecAudioCodecInnerImpl::SyncCodecAdapter::GetProducer()
522 {
523     return innerBufferQueue_ != nullptr ? innerBufferQueue_->GetProducer() : nullptr;
524 }
525 
WaitFor(std::unique_lock<std::mutex> & lock,int64_t timeoutUs)526 bool AVCodecAudioCodecInnerImpl::SyncCodecAdapter::WaitFor(std::unique_lock<std::mutex> &lock, int64_t timeoutUs)
527 {
528     if (timeoutUs < 0) {
529         outputCV_.wait(lock, [this] { return outputAvaliableNum_ > 0; });
530     } else {
531         return outputCV_.wait_for(
532             lock, std::chrono::microseconds(timeoutUs), [this] { return outputAvaliableNum_ > 0; });
533     }
534     return true;
535 }
536 } // namespace MediaAVCodec
537 } // namespace OHOS