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> ¶meter)
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> ¶meter)
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