1 /*
2 * Copyright (C) 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 #define AUDIO_DECODER_ADAPTER_CPP
16
17 #include "avcodec_errors.h"
18 #include "common/log.h"
19 #include "meta/meta.h"
20 #include "audio_decoder_adapter.h"
21 #include "scoped_timer.h"
22
23 namespace {
24 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_SYSTEM_PLAYER, "AudioDecoderAdapter"};
25 constexpr int64_t AUDIOCODEC_START_WARNING_MS = 50;
26 }
27
28 namespace OHOS {
29 namespace Media {
30
31 using namespace MediaAVCodec;
32
AudioDecoderAdapter()33 AudioDecoderAdapter::AudioDecoderAdapter()
34 {
35 }
36
~AudioDecoderAdapter()37 AudioDecoderAdapter::~AudioDecoderAdapter()
38 {
39 MEDIA_LOG_I("~AudioDecoderAdapter.");
40 FALSE_RETURN_MSG(audiocodec_ != nullptr, "audiocodec_ is nullptr");
41 audiocodec_->Release();
42 }
43
Init(bool isMimeType,const std::string & name)44 Status AudioDecoderAdapter::Init(bool isMimeType, const std::string &name)
45 {
46 MEDIA_LOG_D("isMimeType is %{public}i, name is %{public}s", isMimeType, name.c_str());
47 if (isMimeType) {
48 audiocodec_ = MediaAVCodec::AudioCodecFactory::CreateByMime(name, false);
49 } else {
50 audiocodec_ = MediaAVCodec::AudioCodecFactory::CreateByName(name);
51 }
52 FALSE_RETURN_V_MSG(audiocodec_ != nullptr, Status::ERROR_INVALID_STATE, "audiocodec_ is nullptr");
53 return Status::OK;
54 }
55
Configure(const std::shared_ptr<Meta> & parameter)56 Status AudioDecoderAdapter::Configure(const std::shared_ptr<Meta> ¶meter)
57 {
58 MEDIA_LOG_D("In");
59 FALSE_RETURN_V_MSG(audiocodec_ != nullptr, Status::ERROR_INVALID_STATE, "audiocodec_ is nullptr");
60 int32_t ret = audiocodec_->Configure(parameter);
61 if (ret == AVCodecServiceErrCode::AVCS_ERR_INVALID_VAL) {
62 MEDIA_LOG_E("Configure ret is %{public}d", ret);
63 return Status::ERROR_UNSUPPORTED_FORMAT;
64 }
65 FALSE_RETURN_V(ret == AVCodecServiceErrCode::AVCS_ERR_OK, Status::ERROR_INVALID_STATE);
66 MEDIA_LOG_D("out");
67 return Status::OK;
68 }
69
SetParameter(const std::shared_ptr<Meta> & parameter)70 Status AudioDecoderAdapter::SetParameter(const std::shared_ptr<Meta> ¶meter)
71 {
72 MEDIA_LOG_D("In");
73 FALSE_RETURN_V_MSG(audiocodec_ != nullptr, Status::ERROR_INVALID_STATE, "audiocodec_ is nullptr");
74 FALSE_RETURN_V(parameter != nullptr, Status::ERROR_INVALID_PARAMETER);
75 int32_t ret = audiocodec_->SetParameter(parameter);
76 return ret == AVCodecServiceErrCode::AVCS_ERR_OK ? Status::OK : Status::ERROR_INVALID_STATE;
77 }
78
Prepare()79 Status AudioDecoderAdapter::Prepare()
80 {
81 MEDIA_LOG_D("In");
82 FALSE_RETURN_V_MSG(audiocodec_ != nullptr, Status::ERROR_INVALID_STATE, "audiocodec_ is nullptr");
83 int32_t ret = audiocodec_->Prepare();
84 FALSE_RETURN_V(ret == AVCodecServiceErrCode::AVCS_ERR_OK, Status::ERROR_INVALID_STATE);
85 isRunning_ = false;
86 MEDIA_LOG_D("out");
87 return Status::OK;
88 }
89
Start()90 Status AudioDecoderAdapter::Start()
91 {
92 MEDIA_LOG_D("In");
93 if (isRunning_.load()) {
94 return Status::OK;
95 }
96 FALSE_RETURN_V_MSG(audiocodec_ != nullptr, Status::ERROR_INVALID_STATE, "audiocodec_ is nullptr");
97 int32_t ret;
98 {
99 ScopedTimer timer("AudioCodec Start", AUDIOCODEC_START_WARNING_MS);
100 ret = audiocodec_->Start();
101 }
102 FALSE_RETURN_V(ret == AVCodecServiceErrCode::AVCS_ERR_OK, Status::ERROR_INVALID_STATE);
103 isRunning_ = true;
104 MEDIA_LOG_D("out");
105 return Status::OK;
106 }
107
Stop()108 Status AudioDecoderAdapter::Stop()
109 {
110 MEDIA_LOG_D("In");
111 FALSE_RETURN_V_MSG(audiocodec_ != nullptr, Status::OK, "audiocodec_ is nullptr");
112 int32_t ret = audiocodec_->Stop();
113 FALSE_RETURN_V(ret == AVCodecServiceErrCode::AVCS_ERR_OK, Status::ERROR_INVALID_STATE);
114 isRunning_ = false;
115 MEDIA_LOG_D("out");
116 return Status::OK;
117 }
118
Flush()119 Status AudioDecoderAdapter::Flush()
120 {
121 MEDIA_LOG_D("In");
122 FALSE_RETURN_V_MSG(audiocodec_ != nullptr, Status::ERROR_INVALID_STATE, "audiocodec_ is nullptr");
123 int32_t ret = audiocodec_->Flush();
124 FALSE_RETURN_V(ret == AVCodecServiceErrCode::AVCS_ERR_OK, Status::ERROR_INVALID_STATE);
125 isRunning_ = false;
126 MEDIA_LOG_D("out");
127 return Status::OK;
128 }
129
Reset()130 Status AudioDecoderAdapter::Reset()
131 {
132 MEDIA_LOG_D("In");
133 FALSE_RETURN_V_MSG(audiocodec_ != nullptr, Status::OK, "audiocodec_ is nullptr");
134 int32_t ret = audiocodec_->Reset();
135 FALSE_RETURN_V(ret == AVCodecServiceErrCode::AVCS_ERR_OK, Status::ERROR_INVALID_STATE);
136 isRunning_ = false;
137 MEDIA_LOG_D("out");
138 return Status::OK;
139 }
140
Release()141 Status AudioDecoderAdapter::Release()
142 {
143 MEDIA_LOG_D("In");
144 FALSE_RETURN_V_MSG(audiocodec_ != nullptr, Status::OK, "audiocodec_ is nullptr");
145 int32_t ret = audiocodec_->Release();
146 FALSE_RETURN_V(ret == AVCodecServiceErrCode::AVCS_ERR_OK, Status::ERROR_INVALID_STATE);
147 isRunning_ = false;
148 MEDIA_LOG_D("out");
149 return Status::OK;
150 }
151
SetOutputBufferQueue(const sptr<Media::AVBufferQueueProducer> & bufferQueueProducer)152 Status AudioDecoderAdapter::SetOutputBufferQueue(const sptr<Media::AVBufferQueueProducer> &bufferQueueProducer)
153 {
154 FALSE_RETURN_V(bufferQueueProducer != nullptr, Status::ERROR_INVALID_PARAMETER);
155 outputBufferQueueProducer_ = bufferQueueProducer;
156 FALSE_RETURN_V_MSG(audiocodec_ != nullptr, Status::ERROR_INVALID_STATE, "audiocodec_ is nullptr");
157 int32_t ret = audiocodec_->SetOutputBufferQueue(bufferQueueProducer);
158 return ret == AVCodecServiceErrCode::AVCS_ERR_OK ? Status::OK : Status::ERROR_INVALID_STATE;
159 }
160
GetInputBufferQueue()161 sptr<Media::AVBufferQueueProducer> AudioDecoderAdapter::GetInputBufferQueue()
162 {
163 FALSE_RETURN_V_MSG(audiocodec_ != nullptr, nullptr, "audiocodec_ is nullptr");
164 inputBufferQueueProducer_ = audiocodec_->GetInputBufferQueue();
165 return inputBufferQueueProducer_;
166 }
167
GetInputBufferQueueConsumer()168 sptr<Media::AVBufferQueueConsumer> AudioDecoderAdapter::GetInputBufferQueueConsumer()
169 {
170 return audiocodec_ != nullptr ? audiocodec_->GetInputBufferQueueConsumer() : nullptr;
171 }
172
GetOutputBufferQueueProducer()173 sptr<Media::AVBufferQueueProducer> AudioDecoderAdapter::GetOutputBufferQueueProducer()
174 {
175 return audiocodec_ != nullptr ? audiocodec_->GetOutputBufferQueueProducer() : nullptr;
176 }
177
ProcessInputBufferInner(bool isTriggeredByOutPort,bool isFlushed,uint32_t & bufferStatus)178 void AudioDecoderAdapter::ProcessInputBufferInner(bool isTriggeredByOutPort, bool isFlushed, uint32_t &bufferStatus)
179 {
180 FALSE_RETURN_MSG(audiocodec_ != nullptr, "ProcessInputBufferInner audiocodec_ is nullptr");
181 audiocodec_->ProcessInputBufferInner(isTriggeredByOutPort, isFlushed, bufferStatus);
182 }
183
GetOutputFormat(std::shared_ptr<Meta> & parameter)184 int32_t AudioDecoderAdapter::GetOutputFormat(std::shared_ptr<Meta> ¶meter)
185 {
186 FALSE_RETURN_V(parameter != nullptr, (int32_t)Status::ERROR_INVALID_PARAMETER);
187 FALSE_RETURN_V_MSG(audiocodec_ != nullptr, (int32_t)Status::ERROR_INVALID_STATE, "audiocodec_ is nullptr");
188 return audiocodec_->GetOutputFormat(parameter);
189 }
190
ChangePlugin(const std::string & mime,bool isEncoder,const std::shared_ptr<Meta> & meta)191 Status AudioDecoderAdapter::ChangePlugin(const std::string &mime, bool isEncoder, const std::shared_ptr<Meta> &meta)
192 {
193 FALSE_RETURN_V(meta != nullptr, Status::ERROR_INVALID_PARAMETER);
194 FALSE_RETURN_V_MSG(audiocodec_ != nullptr, Status::ERROR_INVALID_STATE, "audiocodec_ is nullptr");
195 int32_t ret = audiocodec_->ChangePlugin(mime, isEncoder, meta);
196 return ret == AVCodecServiceErrCode::AVCS_ERR_OK ? Status::OK : Status::ERROR_INVALID_STATE;
197 }
198
SetDumpInfo(bool isDump,uint64_t instanceId)199 void AudioDecoderAdapter::SetDumpInfo(bool isDump, uint64_t instanceId)
200 {
201 FALSE_RETURN_MSG(audiocodec_ != nullptr, "audiocodec_ is nullptr");
202 audiocodec_->SetDumpInfo(isDump, instanceId);
203 }
204
OnDumpInfo(int32_t fd)205 void AudioDecoderAdapter::OnDumpInfo(int32_t fd)
206 {
207 MEDIA_LOG_D("OnDumpInfo called.");
208 FALSE_RETURN_MSG(fd >= 0, "OnDumpInfo fd is invalid.");
209 std::string dumpString;
210 FALSE_RETURN_MSG(inputBufferQueueProducer_ != nullptr, "inputBufferQueueProducer_ is nullptr");
211 FALSE_RETURN_MSG(outputBufferQueueProducer_ != nullptr, "outputBufferQueueProducer_ is nullptr");
212 dumpString += "AudioDecoderAdapter inputBufferQueueProducer_ size is:" +
213 std::to_string(inputBufferQueueProducer_->GetQueueSize()) + "\n";
214 dumpString += "AudioDecoderAdapter outputBufferQueueProducer_ size is:" +
215 std::to_string(outputBufferQueueProducer_->GetQueueSize()) + "\n";
216 int ret = write(fd, dumpString.c_str(), dumpString.size());
217 FALSE_RETURN_MSG(ret >= 0, "AudioDecoderAdapter::OnDumpInfo write failed.");
218 }
219
NotifyEos()220 int32_t AudioDecoderAdapter::NotifyEos()
221 {
222 FALSE_RETURN_V_MSG(audiocodec_ != nullptr, (int32_t)Status::ERROR_INVALID_STATE, "audiocodec_ is nullptr");
223 int ret = audiocodec_->NotifyEos();
224 return ret;
225 }
226
SetCodecCallback(const std::shared_ptr<MediaAVCodec::MediaCodecCallback> & codecCallback)227 int32_t AudioDecoderAdapter::SetCodecCallback(const std::shared_ptr<MediaAVCodec::MediaCodecCallback> &codecCallback)
228 {
229 FALSE_RETURN_V_MSG(audiocodec_ != nullptr, (int32_t)Status::ERROR_INVALID_STATE, "audiocodec_ is nullptr");
230 return audiocodec_->SetCodecCallback(codecCallback);
231 }
232
SetAudioDecryptionConfig(const sptr<DrmStandard::IMediaKeySessionService> & keySession,const bool svpFlag)233 int32_t AudioDecoderAdapter::SetAudioDecryptionConfig(
234 const sptr<DrmStandard::IMediaKeySessionService> &keySession, const bool svpFlag)
235 {
236 FALSE_RETURN_V_MSG(audiocodec_ != nullptr, (int32_t)Status::ERROR_INVALID_STATE, "audiocodec_ is nullptr");
237 return audiocodec_->SetAudioDecryptionConfig(keySession, svpFlag);
238 }
239
240 } // namespace Media
241 } // namespace OHOS
242