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 "media_codec.h"
16 #include <shared_mutex>
17 #include "avcodec_common.h"
18 #include "common/log.h"
19 #include "osal/task/autolock.h"
20 #include "plugin/plugin_manager_v2.h"
21 #include "avcodec_log.h"
22 #include "osal/utils/dump_buffer.h"
23 #include "avcodec_trace.h"
24 #include "bundle_mgr_interface.h"
25 #include "iservice_registry.h"
26 #include "system_ability_definition.h"
27 #ifdef SUPPORT_DRM
28 #include "i_keysession_service.h"
29 #endif
30
31 namespace {
32 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_AUDIO, "MediaCodec" };
33 const std::string INPUT_BUFFER_QUEUE_NAME = "MediaCodecInputBufferQueue";
34 constexpr int8_t RETRY = 3; // max retry count is 3
35 constexpr int32_t DEFAULT_BUFFER_NUM = 8;
36 constexpr int32_t TIME_OUT_MS = 50;
37 constexpr int32_t TIME_OUT_MS_INNER = 1;
38 constexpr uint32_t API_SUPPORT_AUDIO_FORMAT_CHANGED = 15;
39 constexpr uint32_t INVALID_API_VERSION = 0;
40 constexpr uint32_t API_VERSION_MOD = 1000;
41 const std::string DUMP_PARAM = "a";
42 const std::string DUMP_FILE_NAME = "player_audio_decoder_output.pcm";
43 } // namespace
44
45 namespace OHOS {
46 namespace Media {
47 class InputBufferAvailableListener : public IConsumerListener {
48 public:
InputBufferAvailableListener(std::shared_ptr<MediaCodec> mediaCodec)49 explicit InputBufferAvailableListener(std::shared_ptr<MediaCodec> mediaCodec)
50 {
51 mediaCodec_ = mediaCodec;
52 }
53
OnBufferAvailable()54 void OnBufferAvailable() override
55 {
56 auto realPtr = mediaCodec_.lock();
57 if (realPtr != nullptr) {
58 realPtr->ProcessInputBuffer();
59 } else {
60 MEDIA_LOG_W("mediacodec was released, can not process input buffer");
61 }
62 }
63
64 private:
65 std::weak_ptr<MediaCodec> mediaCodec_;
66 };
67
MediaCodec()68 MediaCodec::MediaCodec()
69 : codecPlugin_(nullptr),
70 inputBufferQueue_(nullptr),
71 inputBufferQueueProducer_(nullptr),
72 inputBufferQueueConsumer_(nullptr),
73 outputBufferQueueProducer_(nullptr),
74 isEncoder_(false),
75 isSurfaceMode_(false),
76 isBufferMode_(false),
77 outputBufferCapacity_(0),
78 state_(CodecState::UNINITIALIZED)
79 {
80 }
81
~MediaCodec()82 MediaCodec::~MediaCodec()
83 {
84 state_ = CodecState::UNINITIALIZED;
85 outputBufferCapacity_ = 0;
86 if (codecPlugin_) {
87 codecPlugin_ = nullptr;
88 }
89 if (inputBufferQueue_) {
90 inputBufferQueue_ = nullptr;
91 }
92 if (inputBufferQueueProducer_) {
93 inputBufferQueueProducer_ = nullptr;
94 }
95 if (inputBufferQueueConsumer_) {
96 inputBufferQueueConsumer_ = nullptr;
97 }
98 if (outputBufferQueueProducer_) {
99 outputBufferQueueProducer_ = nullptr;
100 }
101 }
102
Init(const std::string & mime,bool isEncoder)103 int32_t MediaCodec::Init(const std::string &mime, bool isEncoder)
104 {
105 AutoLock lock(stateMutex_);
106 MediaAVCodec::AVCodecTrace trace("MediaCodec::Init");
107 MEDIA_LOG_I("Init enter, mime: " PUBLIC_LOG_S, mime.c_str());
108 if (state_ != CodecState::UNINITIALIZED) {
109 MEDIA_LOG_E("Init failed, state = %{public}s .", StateToString(state_).data());
110 return (int32_t)Status::ERROR_INVALID_STATE;
111 }
112 MEDIA_LOG_I("state from %{public}s to INITIALIZING", StateToString(state_).data());
113 state_ = CodecState::INITIALIZING;
114 Plugins::PluginType type;
115 if (isEncoder) {
116 type = Plugins::PluginType::AUDIO_ENCODER;
117 } else {
118 type = Plugins::PluginType::AUDIO_DECODER;
119 }
120 codecPlugin_ = CreatePlugin(mime, type);
121 if (codecPlugin_ != nullptr) {
122 MEDIA_LOG_I("codecPlugin_->Init()");
123 auto ret = codecPlugin_->Init();
124 FALSE_RETURN_V_MSG_E(ret == Status::OK, (int32_t)ret, "pluign init failed");
125 state_ = CodecState::INITIALIZED;
126 } else {
127 MEDIA_LOG_I("createPlugin failed");
128 return (int32_t)Status::ERROR_INVALID_PARAMETER;
129 }
130 return (int32_t)Status::OK;
131 }
132
Init(const std::string & name)133 int32_t MediaCodec::Init(const std::string &name)
134 {
135 AutoLock lock(stateMutex_);
136 MEDIA_LOG_I("Init enter, name: " PUBLIC_LOG_S, name.c_str());
137 MediaAVCodec::AVCodecTrace trace("MediaCodec::Init");
138 if (state_ != CodecState::UNINITIALIZED) {
139 MEDIA_LOG_E("Init failed, state = %{public}s .", StateToString(state_).data());
140 return (int32_t)Status::ERROR_INVALID_STATE;
141 }
142 MEDIA_LOG_I("state from %{public}s to INITIALIZING", StateToString(state_).data());
143 state_ = CodecState::INITIALIZING;
144 auto plugin = Plugins::PluginManagerV2::Instance().CreatePluginByName(name);
145 FALSE_RETURN_V_MSG_E(plugin != nullptr, (int32_t)Status::ERROR_INVALID_PARAMETER, "create pluign failed");
146 codecPlugin_ = std::reinterpret_pointer_cast<Plugins::CodecPlugin>(plugin);
147 Status ret = codecPlugin_->Init();
148 FALSE_RETURN_V_MSG_E(ret == Status::OK, (int32_t)Status::ERROR_INVALID_PARAMETER, "pluign init failed");
149 state_ = CodecState::INITIALIZED;
150 return (int32_t)Status::OK;
151 }
152
CreatePlugin(const std::string & mime,Plugins::PluginType pluginType)153 std::shared_ptr<Plugins::CodecPlugin> MediaCodec::CreatePlugin(const std::string &mime, Plugins::PluginType pluginType)
154 {
155 auto plugin = Plugins::PluginManagerV2::Instance().CreatePluginByMime(pluginType, mime);
156 if (plugin == nullptr) {
157 return nullptr;
158 }
159 return std::reinterpret_pointer_cast<Plugins::CodecPlugin>(plugin);
160 }
161
Configure(const std::shared_ptr<Meta> & meta)162 int32_t MediaCodec::Configure(const std::shared_ptr<Meta> &meta)
163 {
164 MEDIA_LOG_I("MediaCodec::configure in");
165 AutoLock lock(stateMutex_);
166 MediaAVCodec::AVCodecTrace trace("MediaCodec::Configure");
167 FALSE_RETURN_V(state_ == CodecState::INITIALIZED, (int32_t)Status::ERROR_INVALID_STATE);
168 auto ret = codecPlugin_->SetParameter(meta);
169 FALSE_RETURN_V(ret == Status::OK, (int32_t)ret);
170 ret = codecPlugin_->SetDataCallback(this);
171 FALSE_RETURN_V(ret == Status::OK, (int32_t)ret);
172 state_ = CodecState::CONFIGURED;
173 return (int32_t)Status::OK;
174 }
175
SetOutputBufferQueue(const sptr<AVBufferQueueProducer> & bufferQueueProducer)176 int32_t MediaCodec::SetOutputBufferQueue(const sptr<AVBufferQueueProducer> &bufferQueueProducer)
177 {
178 AutoLock lock(stateMutex_);
179 MediaAVCodec::AVCodecTrace trace("MediaCodec::SetOutputBufferQueue");
180 FALSE_RETURN_V(state_ == CodecState::INITIALIZED || state_ == CodecState::CONFIGURED,
181 (int32_t)Status::ERROR_INVALID_STATE);
182 outputBufferQueueProducer_ = bufferQueueProducer;
183 isBufferMode_ = true;
184 return (int32_t)Status::OK;
185 }
186
SetCodecCallback(const std::shared_ptr<CodecCallback> & codecCallback)187 int32_t MediaCodec::SetCodecCallback(const std::shared_ptr<CodecCallback> &codecCallback)
188 {
189 AutoLock lock(stateMutex_);
190 FALSE_RETURN_V(state_ == CodecState::INITIALIZED || state_ == CodecState::CONFIGURED,
191 (int32_t)Status::ERROR_INVALID_STATE);
192 FALSE_RETURN_V_MSG_E(codecCallback != nullptr, (int32_t)Status::ERROR_INVALID_PARAMETER,
193 "codecCallback is nullptr");
194 codecCallback_ = codecCallback;
195 auto ret = codecPlugin_->SetDataCallback(this);
196 FALSE_RETURN_V(ret == Status::OK, (int32_t)ret);
197 return (int32_t)Status::OK;
198 }
199
SetCodecCallback(const std::shared_ptr<AudioBaseCodecCallback> & codecCallback)200 int32_t MediaCodec::SetCodecCallback(const std::shared_ptr<AudioBaseCodecCallback> &codecCallback)
201 {
202 AutoLock lock(stateMutex_);
203 FALSE_RETURN_V(state_ == CodecState::INITIALIZED || state_ == CodecState::CONFIGURED,
204 (int32_t)Status::ERROR_INVALID_STATE);
205 FALSE_RETURN_V_MSG_E(codecCallback != nullptr, (int32_t)Status::ERROR_INVALID_PARAMETER,
206 "codecCallback is nullptr");
207 mediaCodecCallback_ = codecCallback;
208 uint32_t apiVersion = GetApiVersion();
209 isSupportAudioFormatChanged_ =
210 ((apiVersion == INVALID_API_VERSION) || (apiVersion >= API_SUPPORT_AUDIO_FORMAT_CHANGED));
211 return (int32_t)Status::OK;
212 }
213
SetOutputSurface(sptr<Surface> surface)214 int32_t MediaCodec::SetOutputSurface(sptr<Surface> surface)
215 {
216 AutoLock lock(stateMutex_);
217 FALSE_RETURN_V(state_ == CodecState::INITIALIZED || state_ == CodecState::CONFIGURED,
218 (int32_t)Status::ERROR_INVALID_STATE);
219 isSurfaceMode_ = true;
220 return (int32_t)Status::OK;
221 }
222
Prepare()223 int32_t MediaCodec::Prepare()
224 {
225 MEDIA_LOG_I("Prepare enter");
226 AutoLock lock(stateMutex_);
227 MediaAVCodec::AVCodecTrace trace("MediaCodec::Prepare");
228 FALSE_RETURN_V_MSG_W(state_ != CodecState::FLUSHED, (int32_t)Status::ERROR_AGAIN,
229 "state is flushed, no need prepare");
230 FALSE_RETURN_V(state_ != CodecState::PREPARED, (int32_t)Status::OK);
231 FALSE_RETURN_V(state_ == CodecState::CONFIGURED,
232 (int32_t)Status::ERROR_INVALID_STATE);
233 if (isBufferMode_ && isSurfaceMode_) {
234 MEDIA_LOG_E("state error");
235 return (int32_t)Status::ERROR_UNKNOWN;
236 }
237 outputBufferCapacity_ = 0;
238 auto ret = (int32_t)PrepareInputBufferQueue();
239 CHECK_AND_RETURN_RET_LOG(ret == (int32_t)Status::OK, (int32_t)ret, "PrepareInputBufferQueue failed");
240 ret = (int32_t)PrepareOutputBufferQueue();
241 CHECK_AND_RETURN_RET_LOG(ret == (int32_t)Status::OK, (int32_t)ret, "PrepareOutputBufferQueue failed");
242 state_ = CodecState::PREPARED;
243 MEDIA_LOG_I("Prepare, ret = %{public}d", (int32_t)ret);
244 return (int32_t)Status::OK;
245 }
246
GetInputBufferQueue()247 sptr<AVBufferQueueProducer> MediaCodec::GetInputBufferQueue()
248 {
249 AutoLock lock(stateMutex_);
250 FALSE_RETURN_V(state_ == CodecState::PREPARED, sptr<AVBufferQueueProducer>());
251 CHECK_AND_RETURN_RET_LOG(!isSurfaceMode_, nullptr, "GetInputBufferQueue isSurfaceMode_");
252 isBufferMode_ = true;
253 return inputBufferQueueProducer_;
254 }
255
GetInputBufferQueueConsumer()256 sptr<AVBufferQueueConsumer> MediaCodec::GetInputBufferQueueConsumer()
257 {
258 AutoLock lock(stateMutex_);
259 // Case: to enable to set listener to input bufferqueue consumer. i.e. input bufferqueue updating by ChangePlugin.
260 FALSE_RETURN_V(state_ == CodecState::PREPARED || state_ == CodecState::RUNNING ||
261 state_ == CodecState::FLUSHED || state_ == CodecState::END_OF_STREAM, sptr<AVBufferQueueConsumer>());
262 CHECK_AND_RETURN_RET_LOG(!isSurfaceMode_, nullptr, "GetInputBufferQueueConsumer isSurfaceMode_");
263 isBufferMode_ = true;
264 return inputBufferQueueConsumer_;
265 }
266
GetOutputBufferQueueProducer()267 sptr<AVBufferQueueProducer> MediaCodec::GetOutputBufferQueueProducer()
268 {
269 AutoLock lock(stateMutex_);
270 // Case: to enable to set listener to output bufferqueue producer. i.e. output bufferqueue updating by ChangePlugin.
271 FALSE_RETURN_V(state_ == CodecState::PREPARED || state_ == CodecState::RUNNING ||
272 state_ == CodecState::FLUSHED || state_ == CodecState::END_OF_STREAM, sptr<AVBufferQueueProducer>());
273 CHECK_AND_RETURN_RET_LOG(!isSurfaceMode_, nullptr, "GetOutputBufferQueueProducer isSurfaceMode_");
274
275 return outputBufferQueueProducer_;
276 }
277
ProcessInputBufferInner(bool isTriggeredByOutPort,bool isFlushed)278 void MediaCodec::ProcessInputBufferInner(bool isTriggeredByOutPort, bool isFlushed)
279 {
280 MEDIA_LOG_D("ProcessInputBufferInnerr isTriggeredByOutPort:" PUBLIC_LOG_D32 ", isFlushed:" PUBLIC_LOG_D32
281 ", isOutputBufferAvailable:" PUBLIC_LOG_D32 ", inputBufferQueueSize:" PUBLIC_LOG_U32
282 ", inputBufferEosStatus:" PUBLIC_LOG_U32, isTriggeredByOutPort, isFlushed, isOutputBufferAvailable_.load(),
283 inputBufferQueueConsumer_->GetFilledBufferSize(), inputBufferEosStatus_.load());
284 FALSE_RETURN_MSG(!isFlushed, "ProcessInputBufferInner isFlushed true");
285 FALSE_RETURN_MSG(inputBufferQueueConsumer_->GetFilledBufferSize() != 0 || !isOutputBufferAvailable_.load(),
286 "ProcessInputBufferInner ignore");
287
288 MediaAVCodec::AVCodecTrace trace("MediaCodec::ProcessInputBufferInner");
289 Status ret = Status::OK;
290
291 // The last process failed to RequestBuffer from outputBufferQueueProducer, perform HandleOutputBufferInner firstly.
292 if (!isOutputBufferAvailable_.load() || inputBufferEosStatus_.load() != 0) {
293 CHECK_AND_RETURN_LOGD(HandleOutputBufferInner(ret), "S1 output buffer unavailable, ret:%{public}d", ret);
294 inputBufferEosStatus_.store(0);
295 }
296
297 bool isProcessingNeeded = false;
298 uint32_t eosStatus = 0;
299 ret = Status::OK;
300 HandleInputBufferInner(eosStatus, isProcessingNeeded, ret);
301 CHECK_AND_RETURN_LOG(isProcessingNeeded, "ProcessInputBufferInner failed %{public}d", static_cast<int32_t>(ret));
302
303 inputBufferEosStatus_ = eosStatus;
304 CHECK_AND_RETURN_LOGD(HandleOutputBufferInner(ret), "S2 output buffer unavailable, ret:%{public}d", ret);
305 inputBufferEosStatus_.store(0);
306 }
307
HandleOutputBufferInner(Status & ret)308 bool MediaCodec::HandleOutputBufferInner(Status &ret)
309 {
310 MediaAVCodec::AVCodecTrace trace("MediaCodec::HandleOutputBufferInner");
311 bool isBufferAvailable = false;
312 do {
313 isBufferAvailable = false;
314 ret = HandleOutputBufferOnce(isBufferAvailable, inputBufferEosStatus_.load(), false);
315 } while (ret == Status::ERROR_AGAIN);
316 MEDIA_LOG_D("HandleOutputBufferInner ret:%{public}d, isBufferAvailable:%{public}d", ret, isBufferAvailable);
317 isOutputBufferAvailable_.store(isBufferAvailable);
318 return isBufferAvailable;
319 }
320
GetInputSurface()321 sptr<Surface> MediaCodec::GetInputSurface()
322 {
323 AutoLock lock(stateMutex_);
324 FALSE_RETURN_V(state_ == CodecState::PREPARED, nullptr);
325 CHECK_AND_RETURN_RET_LOG(!isBufferMode_, nullptr, "GetInputBufferQueue isBufferMode_");
326 isSurfaceMode_ = true;
327 return nullptr;
328 }
329
Start()330 int32_t MediaCodec::Start()
331 {
332 AutoLock lock(stateMutex_);
333 MEDIA_LOG_I("Start enter");
334 MediaAVCodec::AVCodecTrace trace("MediaCodec::Start");
335 FALSE_RETURN_V(state_ != CodecState::RUNNING, (int32_t)Status::OK);
336 FALSE_RETURN_V(state_ == CodecState::PREPARED || state_ == CodecState::FLUSHED,
337 (int32_t)Status::ERROR_INVALID_STATE);
338 state_ = CodecState::STARTING;
339 auto ret = codecPlugin_->Start();
340 FALSE_RETURN_V_MSG_E(ret == Status::OK, (int32_t)ret, "plugin start failed");
341 state_ = CodecState::RUNNING;
342 return (int32_t)ret;
343 }
344
Stop()345 int32_t MediaCodec::Stop()
346 {
347 AutoLock lock(stateMutex_);
348 MediaAVCodec::AVCodecTrace trace("MediaCodec::Stop");
349 MEDIA_LOG_I("Stop enter");
350 FALSE_RETURN_V(state_ != CodecState::PREPARED, (int32_t)Status::OK);
351 if (state_ == CodecState::UNINITIALIZED || state_ == CodecState::STOPPING || state_ == CodecState::RELEASING) {
352 MEDIA_LOG_D("Stop, state_=%{public}s", StateToString(state_).data());
353 return (int32_t)Status::OK;
354 }
355 FALSE_RETURN_V(state_ == CodecState::RUNNING || state_ == CodecState::END_OF_STREAM ||
356 state_ == CodecState::FLUSHED, (int32_t)Status::ERROR_INVALID_STATE);
357 state_ = CodecState::STOPPING;
358 auto ret = codecPlugin_->Stop();
359 MEDIA_LOG_I("codec Stop, state from %{public}s to Stop", StateToString(state_).data());
360 FALSE_RETURN_V_MSG_E(ret == Status::OK, (int32_t)ret, "plugin stop failed");
361 ClearInputBuffer();
362 inputBufferEosStatus_.store(0);
363 isOutputBufferAvailable_.store(true);
364 state_ = CodecState::PREPARED;
365 return (int32_t)ret;
366 }
367
Flush()368 int32_t MediaCodec::Flush()
369 {
370 AutoLock lock(stateMutex_);
371 MEDIA_LOG_I("Flush enter");
372 if (state_ == CodecState::FLUSHED) {
373 MEDIA_LOG_W("Flush, state is already flushed, state_=%{public}s .", StateToString(state_).data());
374 return (int32_t)Status::OK;
375 }
376 if (state_ != CodecState::RUNNING && state_ != CodecState::END_OF_STREAM) {
377 MEDIA_LOG_E("Flush failed, state =%{public}s", StateToString(state_).data());
378 return (int32_t)Status::ERROR_INVALID_STATE;
379 }
380 MEDIA_LOG_I("Flush, state from %{public}s to FLUSHING", StateToString(state_).data());
381 state_ = CodecState::FLUSHING;
382 inputBufferQueueProducer_->Clear();
383 auto ret = codecPlugin_->Flush();
384 FALSE_RETURN_V_MSG_E(ret == Status::OK, (int32_t)ret, "plugin flush failed");
385 ClearInputBuffer();
386 inputBufferEosStatus_.store(0);
387 isOutputBufferAvailable_.store(true);
388 state_ = CodecState::FLUSHED;
389 return (int32_t)ret;
390 }
391
Reset()392 int32_t MediaCodec::Reset()
393 {
394 AutoLock lock(stateMutex_);
395 MediaAVCodec::AVCodecTrace trace("MediaCodec::Reset");
396 MEDIA_LOG_I("Reset enter");
397 if (state_ == CodecState::UNINITIALIZED || state_ == CodecState::RELEASING) {
398 MEDIA_LOG_W("adapter reset, state is already released, state =%{public}s .", StateToString(state_).data());
399 return (int32_t)Status::OK;
400 }
401 if (state_ == CodecState::INITIALIZING) {
402 MEDIA_LOG_W("adapter reset, state is initialized, state =%{public}s .", StateToString(state_).data());
403 state_ = CodecState::INITIALIZED;
404 return (int32_t)Status::OK;
405 }
406 auto ret = codecPlugin_->Reset();
407 FALSE_RETURN_V_MSG_E(ret == Status::OK, (int32_t)ret, "plugin reset failed");
408 ClearInputBuffer();
409 inputBufferEosStatus_.store(0);
410 isOutputBufferAvailable_.store(true);
411 state_ = CodecState::INITIALIZED;
412 return (int32_t)ret;
413 }
414
Release()415 int32_t MediaCodec::Release()
416 {
417 AutoLock lock(stateMutex_);
418 MediaAVCodec::AVCodecTrace trace("MediaCodec::Release");
419 MEDIA_LOG_I("Release enter");
420 if (state_ == CodecState::UNINITIALIZED || state_ == CodecState::RELEASING) {
421 MEDIA_LOG_W("codec Release, state isnot completely correct, state =%{public}s .", StateToString(state_).data());
422 return (int32_t)Status::OK;
423 }
424
425 if (state_ == CodecState::INITIALIZING) {
426 MEDIA_LOG_W("codec Release, state isnot completely correct, state =%{public}s .", StateToString(state_).data());
427 state_ = CodecState::RELEASING;
428 return (int32_t)Status::OK;
429 }
430 MEDIA_LOG_I("codec Release, state from %{public}s to RELEASING", StateToString(state_).data());
431 state_ = CodecState::RELEASING;
432 auto ret = codecPlugin_->Release();
433 FALSE_RETURN_V_MSG_E(ret == Status::OK, (int32_t)ret, "plugin release failed");
434 codecPlugin_ = nullptr;
435 ClearBufferQueue();
436 inputBufferEosStatus_.store(0);
437 isOutputBufferAvailable_.store(true);
438 state_ = CodecState::UNINITIALIZED;
439 return (int32_t)ret;
440 }
441
NotifyEos()442 int32_t MediaCodec::NotifyEos()
443 {
444 AutoLock lock(stateMutex_);
445 FALSE_RETURN_V(state_ != CodecState::END_OF_STREAM, (int32_t)Status::OK);
446 FALSE_RETURN_V(state_ == CodecState::RUNNING, (int32_t)Status::ERROR_INVALID_STATE);
447 state_ = CodecState::END_OF_STREAM;
448 return (int32_t)Status::OK;
449 }
450
SetParameter(const std::shared_ptr<Meta> & parameter)451 int32_t MediaCodec::SetParameter(const std::shared_ptr<Meta> ¶meter)
452 {
453 AutoLock lock(stateMutex_);
454 FALSE_RETURN_V(parameter != nullptr, (int32_t)Status::ERROR_INVALID_PARAMETER);
455 FALSE_RETURN_V(state_ != CodecState::UNINITIALIZED && state_ != CodecState::INITIALIZED &&
456 state_ != CodecState::PREPARED, (int32_t)Status::ERROR_INVALID_STATE);
457 auto ret = codecPlugin_->SetParameter(parameter);
458 FALSE_RETURN_V_MSG_E(ret == Status::OK, (int32_t)ret, "plugin set parameter failed");
459 return (int32_t)ret;
460 }
461
SetDumpInfo(bool isDump,uint64_t instanceId)462 void MediaCodec::SetDumpInfo(bool isDump, uint64_t instanceId)
463 {
464 if (isDump && instanceId == 0) {
465 MEDIA_LOG_W("Cannot dump with instanceId 0.");
466 return;
467 }
468 dumpPrefix_ = std::to_string(instanceId);
469 isDump_ = isDump;
470 }
471
GetOutputFormat(std::shared_ptr<Meta> & parameter)472 int32_t MediaCodec::GetOutputFormat(std::shared_ptr<Meta> ¶meter)
473 {
474 AutoLock lock(stateMutex_);
475 FALSE_RETURN_V_MSG_E(state_ != CodecState::UNINITIALIZED, (int32_t)Status::ERROR_INVALID_STATE,
476 "status incorrect,get output format failed.");
477 FALSE_RETURN_V(codecPlugin_ != nullptr, (int32_t)Status::ERROR_INVALID_STATE);
478 FALSE_RETURN_V(parameter != nullptr, (int32_t)Status::ERROR_INVALID_PARAMETER);
479 auto ret = codecPlugin_->GetParameter(parameter);
480 FALSE_RETURN_V_MSG_E(ret == Status::OK, (int32_t)ret, "plugin get parameter failed");
481 return (int32_t)ret;
482 }
483
AttachBufffer()484 Status MediaCodec::AttachBufffer()
485 {
486 MEDIA_LOG_I("AttachBufffer enter");
487 int inputBufferNum = DEFAULT_BUFFER_NUM;
488 MemoryType memoryType;
489 #ifndef MEDIA_OHOS
490 memoryType = MemoryType::VIRTUAL_MEMORY;
491 #else
492 memoryType = MemoryType::SHARED_MEMORY;
493 #endif
494 if (inputBufferQueue_ == nullptr) {
495 inputBufferQueue_ = AVBufferQueue::Create(inputBufferNum, memoryType, INPUT_BUFFER_QUEUE_NAME);
496 }
497 FALSE_RETURN_V_MSG_E(inputBufferQueue_ != nullptr, Status::ERROR_UNKNOWN,
498 "inputBufferQueue_ is nullptr");
499 inputBufferQueueProducer_ = inputBufferQueue_->GetProducer();
500 std::shared_ptr<Meta> inputBufferConfig = std::make_shared<Meta>();
501 FALSE_RETURN_V_MSG_E(codecPlugin_ != nullptr, Status::ERROR_UNKNOWN, "codecPlugin_ is nullptr");
502 auto ret = codecPlugin_->GetParameter(inputBufferConfig);
503 FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "attachBufffer failed, plugin get param error");
504 int32_t capacity = 0;
505 FALSE_RETURN_V_MSG_E(inputBufferConfig != nullptr, Status::ERROR_UNKNOWN,
506 "inputBufferConfig is nullptr");
507 FALSE_RETURN_V(inputBufferConfig->Get<Tag::AUDIO_MAX_INPUT_SIZE>(capacity),
508 Status::ERROR_INVALID_PARAMETER);
509 for (int i = 0; i < inputBufferNum; i++) {
510 std::shared_ptr<AVAllocator> avAllocator;
511 #ifndef MEDIA_OHOS
512 MEDIA_LOG_D("CreateVirtualAllocator,i=%{public}d capacity=%{public}d", i, capacity);
513 avAllocator = AVAllocatorFactory::CreateVirtualAllocator();
514 #else
515 MEDIA_LOG_D("CreateSharedAllocator,i=%{public}d capacity=%{public}d", i, capacity);
516 avAllocator = AVAllocatorFactory::CreateSharedAllocator(MemoryFlag::MEMORY_READ_WRITE);
517 #endif
518 std::shared_ptr<AVBuffer> inputBuffer = AVBuffer::CreateAVBuffer(avAllocator, capacity);
519 FALSE_RETURN_V_MSG_E(inputBuffer != nullptr, Status::ERROR_UNKNOWN,
520 "inputBuffer is nullptr");
521 FALSE_RETURN_V_MSG_E(inputBufferQueueProducer_ != nullptr, Status::ERROR_UNKNOWN,
522 "inputBufferQueueProducer_ is nullptr");
523 inputBufferQueueProducer_->AttachBuffer(inputBuffer, false);
524 MEDIA_LOG_I("Attach intput buffer. index: %{public}d, bufferId: %{public}" PRIu64,
525 i, inputBuffer->GetUniqueId());
526 inputBufferVector_.push_back(inputBuffer);
527 }
528 return Status::OK;
529 }
530
AttachDrmBufffer(std::shared_ptr<AVBuffer> & drmInbuf,std::shared_ptr<AVBuffer> & drmOutbuf,uint32_t size)531 Status MediaCodec::AttachDrmBufffer(std::shared_ptr<AVBuffer> &drmInbuf, std::shared_ptr<AVBuffer> &drmOutbuf,
532 uint32_t size)
533 {
534 MEDIA_LOG_D("AttachDrmBufffer");
535 std::shared_ptr<AVAllocator> avAllocator;
536 avAllocator = AVAllocatorFactory::CreateSharedAllocator(MemoryFlag::MEMORY_READ_WRITE);
537 FALSE_RETURN_V_MSG_E(avAllocator != nullptr, Status::ERROR_UNKNOWN,
538 "avAllocator is nullptr");
539
540 drmInbuf = AVBuffer::CreateAVBuffer(avAllocator, size);
541 FALSE_RETURN_V_MSG_E(drmInbuf != nullptr, Status::ERROR_UNKNOWN,
542 "drmInbuf is nullptr");
543 FALSE_RETURN_V_MSG_E(drmInbuf->memory_ != nullptr, Status::ERROR_UNKNOWN,
544 "drmInbuf->memory_ is nullptr");
545 drmInbuf->memory_->SetSize(size);
546
547 drmOutbuf = AVBuffer::CreateAVBuffer(avAllocator, size);
548 FALSE_RETURN_V_MSG_E(drmOutbuf != nullptr, Status::ERROR_UNKNOWN,
549 "drmOutbuf is nullptr");
550 FALSE_RETURN_V_MSG_E(drmOutbuf->memory_ != nullptr, Status::ERROR_UNKNOWN,
551 "drmOutbuf->memory_ is nullptr");
552 drmOutbuf->memory_->SetSize(size);
553 return Status::OK;
554 }
555
DrmAudioCencDecrypt(std::shared_ptr<AVBuffer> & filledInputBuffer)556 Status MediaCodec::DrmAudioCencDecrypt(std::shared_ptr<AVBuffer> &filledInputBuffer)
557 {
558 MEDIA_LOG_D("DrmAudioCencDecrypt enter");
559 Status ret = Status::OK;
560
561 // 1. allocate drm buffer
562 uint32_t bufSize = static_cast<uint32_t>(filledInputBuffer->memory_->GetSize());
563 if (bufSize == 0) {
564 MEDIA_LOG_D("MediaCodec DrmAudioCencDecrypt input buffer size equal 0");
565 return ret;
566 }
567 std::shared_ptr<AVBuffer> drmInBuf;
568 std::shared_ptr<AVBuffer> drmOutBuf;
569 ret = AttachDrmBufffer(drmInBuf, drmOutBuf, bufSize);
570 FALSE_RETURN_V_MSG_E(ret == Status::OK, Status::ERROR_UNKNOWN, "AttachDrmBufffer failed");
571
572 // 2. copy data to drm input buffer
573 int32_t drmRes = memcpy_s(drmInBuf->memory_->GetAddr(), bufSize,
574 filledInputBuffer->memory_->GetAddr(), bufSize);
575 FALSE_RETURN_V_MSG_E(drmRes == 0, Status::ERROR_UNKNOWN, "memcpy_s drmInBuf failed");
576 if (filledInputBuffer->meta_ != nullptr) {
577 *(drmInBuf->meta_) = *(filledInputBuffer->meta_);
578 }
579 // 4. decrypt
580 drmRes = drmDecryptor_->DrmAudioCencDecrypt(drmInBuf, drmOutBuf, bufSize);
581 FALSE_RETURN_V_MSG_E(drmRes == 0, Status::ERROR_DRM_DECRYPT_FAILED, "DrmAudioCencDecrypt return error");
582
583 // 5. copy decrypted data from drm output buffer back
584 drmRes = memcpy_s(filledInputBuffer->memory_->GetAddr(), bufSize,
585 drmOutBuf->memory_->GetAddr(), bufSize);
586 FALSE_RETURN_V_MSG_E(drmRes == 0, Status::ERROR_UNKNOWN, "memcpy_s drmOutBuf failed");
587 return Status::OK;
588 }
589
HandleAudioCencDecryptError()590 void MediaCodec::HandleAudioCencDecryptError()
591 {
592 MEDIA_LOG_E("MediaCodec DrmAudioCencDecrypt failed.");
593 auto realPtr = mediaCodecCallback_.lock();
594 if (realPtr != nullptr) {
595 realPtr->OnError(CodecErrorType::CODEC_DRM_DECRYTION_FAILED,
596 static_cast<int32_t>(Status::ERROR_DRM_DECRYPT_FAILED));
597 }
598 }
599
PrepareInputBufferQueue()600 int32_t MediaCodec::PrepareInputBufferQueue()
601 {
602 MEDIA_LOG_I("PrepareInputBufferQueue enter");
603 std::vector<std::shared_ptr<AVBuffer>> inputBuffers;
604 MediaAVCodec::AVCodecTrace trace("MediaCodec::PrepareInputBufferQueue");
605 FALSE_RETURN_V_MSG_E(codecPlugin_ != nullptr, (int32_t)Status::ERROR_UNKNOWN, "codecPlugin_ is nullptr");
606 auto ret = codecPlugin_->GetInputBuffers(inputBuffers);
607 FALSE_RETURN_V_MSG_E(ret == Status::OK, (int32_t)ret, "pluign getInputBuffers failed");
608 if (inputBuffers.empty()) {
609 ret = AttachBufffer();
610 if (ret != Status::OK) {
611 MEDIA_LOG_E("GetParameter failed");
612 return (int32_t)ret;
613 }
614 } else {
615 if (inputBufferQueue_ == nullptr) {
616 inputBufferQueue_ =
617 AVBufferQueue::Create(inputBuffers.size(), MemoryType::HARDWARE_MEMORY, INPUT_BUFFER_QUEUE_NAME);
618 }
619 FALSE_RETURN_V_MSG_E(inputBufferQueue_ != nullptr, (int32_t)Status::ERROR_UNKNOWN,
620 "inputBufferQueue_ is nullptr");
621 inputBufferQueueProducer_ = inputBufferQueue_->GetProducer();
622 for (uint32_t i = 0; i < inputBuffers.size(); i++) {
623 inputBufferQueueProducer_->AttachBuffer(inputBuffers[i], false);
624 inputBufferVector_.push_back(inputBuffers[i]);
625 }
626 }
627 FALSE_RETURN_V_MSG_E(inputBufferQueue_ != nullptr, (int32_t)Status::ERROR_UNKNOWN, "inputBufferQueue_ is nullptr");
628 inputBufferQueueConsumer_ = inputBufferQueue_->GetConsumer();
629 sptr<IConsumerListener> listener = new InputBufferAvailableListener(shared_from_this());
630 FALSE_RETURN_V_MSG_E(inputBufferQueueConsumer_ != nullptr, (int32_t)Status::ERROR_UNKNOWN,
631 "inputBufferQueueConsumer_ is nullptr");
632 inputBufferQueueConsumer_->SetBufferAvailableListener(listener);
633 return (int32_t)ret;
634 }
635
PrepareOutputBufferQueue()636 int32_t MediaCodec::PrepareOutputBufferQueue()
637 {
638 MEDIA_LOG_I("PrepareOutputBufferQueue enter");
639 std::vector<std::shared_ptr<AVBuffer>> outputBuffers;
640 MediaAVCodec::AVCodecTrace trace("MediaCodec::PrepareOutputBufferQueue");
641 FALSE_RETURN_V_MSG_E(codecPlugin_ != nullptr, (int32_t)Status::ERROR_INVALID_STATE, "codecPlugin_ is nullptr");
642 auto ret = codecPlugin_->GetOutputBuffers(outputBuffers);
643 FALSE_RETURN_V_MSG_E(ret == Status::OK, (int32_t)ret, "GetOutputBuffers failed");
644 FALSE_RETURN_V_MSG_E(outputBufferQueueProducer_ != nullptr, (int32_t)Status::ERROR_INVALID_STATE,
645 "outputBufferQueueProducer_ is nullptr");
646 if (outputBuffers.empty()) {
647 int outputBufferNum = 30;
648 std::shared_ptr<Meta> outputBufferConfig = std::make_shared<Meta>();
649 ret = codecPlugin_->GetParameter(outputBufferConfig);
650 FALSE_RETURN_V_MSG_E(ret == Status::OK, (int32_t)ret, "GetParameter failed");
651 FALSE_RETURN_V_MSG_E(outputBufferConfig != nullptr, (int32_t)Status::ERROR_INVALID_STATE,
652 "outputBufferConfig is nullptr");
653 FALSE_RETURN_V(outputBufferConfig->Get<Tag::AUDIO_MAX_OUTPUT_SIZE>(outputBufferCapacity_),
654 (int32_t)Status::ERROR_INVALID_PARAMETER);
655 for (int i = 0; i < outputBufferNum; i++) {
656 auto avAllocator = AVAllocatorFactory::CreateSharedAllocator(MemoryFlag::MEMORY_READ_WRITE);
657 std::shared_ptr<AVBuffer> outputBuffer = AVBuffer::CreateAVBuffer(avAllocator, outputBufferCapacity_);
658 FALSE_RETURN_V_MSG_E(outputBuffer != nullptr, (int32_t)Status::ERROR_INVALID_STATE,
659 "outputBuffer is nullptr");
660 if (outputBufferQueueProducer_->AttachBuffer(outputBuffer, false) == Status::OK) {
661 MEDIA_LOG_D("Attach output buffer. index: %{public}d, bufferId: %{public}" PRIu64, i,
662 outputBuffer->GetUniqueId());
663 outputBufferVector_.push_back(outputBuffer);
664 }
665 }
666 } else {
667 for (uint32_t i = 0; i < outputBuffers.size(); i++) {
668 if (outputBufferQueueProducer_->AttachBuffer(outputBuffers[i], false) == Status::OK) {
669 MEDIA_LOG_D("Attach output buffer. index: %{public}d, bufferId: %{public}" PRIu64, i,
670 outputBuffers[i]->GetUniqueId());
671 outputBufferVector_.push_back(outputBuffers[i]);
672 }
673 }
674 }
675 FALSE_RETURN_V_MSG_E(outputBufferVector_.size() > 0, (int32_t)Status::ERROR_INVALID_STATE, "Attach no buffer");
676 return (int32_t)ret;
677 }
678
ProcessInputBuffer()679 void MediaCodec::ProcessInputBuffer()
680 {
681 MEDIA_LOG_D("ProcessInputBuffer enter");
682 MediaAVCodec::AVCodecTrace trace("MediaCodec::ProcessInputBuffer");
683
684 bool isProcessingNeeded = false;
685 Status ret = Status::OK;
686 uint32_t eosStatus = 0;
687 HandleInputBufferInner(eosStatus, isProcessingNeeded, ret);
688 CHECK_AND_RETURN_LOG(isProcessingNeeded, "ProcessInputBuffer failed %{public}d", static_cast<int32_t>(ret));
689
690 do {
691 ret = HandleOutputBuffer(eosStatus);
692 } while (ret == Status::ERROR_AGAIN);
693 }
694
HandleInputBufferInner(uint32_t & eosStatus,bool & isProcessingNeeded,Status & ret)695 void MediaCodec::HandleInputBufferInner(uint32_t &eosStatus, bool &isProcessingNeeded, Status &ret)
696 {
697 MediaAVCodec::AVCodecTrace traceHandleInputBufferInner("MediaCodec::HandleInputBufferInner");
698
699 std::shared_ptr<AVBuffer> filledInputBuffer;
700 if (state_ != CodecState::RUNNING) {
701 MEDIA_LOG_I("HandleInputBufferInner status changed, current status is not running");
702 ret = Status::ERROR_INVALID_STATE;
703 return;
704 }
705 {
706 MediaAVCodec::AVCodecTrace traceAcquireBuffer("MediaCodec::HandleInputBufferInner-AcquireBuffer");
707 ret = inputBufferQueueConsumer_->AcquireBuffer(filledInputBuffer);
708 if (ret != Status::OK) {
709 MEDIA_LOG_E("HandleInputBufferInner AcquireBuffer fail");
710 return;
711 }
712 }
713 if (state_ != CodecState::RUNNING) {
714 MEDIA_LOG_D("HandleInputBufferInner not running, ReleaseBuffer name:MediaCodecInputBufferQueue");
715 inputBufferQueueConsumer_->ReleaseBuffer(filledInputBuffer);
716 ret = Status::ERROR_INVALID_STATE;
717 return;
718 }
719 int8_t retryCount = 0;
720 do {
721 if (drmDecryptor_ != nullptr) {
722 MediaAVCodec::AVCodecTrace trace("MediaCodec::HandleInputBufferInner-DrmAudioCencDecrypt");
723 ret = DrmAudioCencDecrypt(filledInputBuffer);
724 if (ret != Status::OK) {
725 HandleAudioCencDecryptError();
726 break;
727 }
728 }
729
730 MediaAVCodec::AVCodecTrace traceQueueInputBuffer("MediaCodec::HandleInputBufferInner-QueueInputBuffer");
731 ret = codecPlugin_->QueueInputBuffer(filledInputBuffer);
732 if (ret != Status::OK) {
733 retryCount++;
734 continue;
735 }
736 } while (ret != Status::OK && retryCount < RETRY && state_ == CodecState::RUNNING);
737
738 if (ret != Status::OK || state_ != CodecState::RUNNING) {
739 inputBufferQueueConsumer_->ReleaseBuffer(filledInputBuffer);
740 MEDIA_LOG_E("Plugin queueInputBuffer failed, state_:%{public}d, ret:%{public}d", state_.load(), ret);
741 return;
742 }
743 isProcessingNeeded = true;
744 eosStatus = filledInputBuffer->flag_;
745 }
746
747 #ifdef SUPPORT_DRM
SetAudioDecryptionConfig(const sptr<DrmStandard::IMediaKeySessionService> & keySession,const bool svpFlag)748 int32_t MediaCodec::SetAudioDecryptionConfig(const sptr<DrmStandard::IMediaKeySessionService> &keySession,
749 const bool svpFlag)
750 {
751 MEDIA_LOG_I("MediaCodec::SetAudioDecryptionConfig");
752 if (drmDecryptor_ == nullptr) {
753 drmDecryptor_ = std::make_shared<MediaAVCodec::CodecDrmDecrypt>();
754 }
755 FALSE_RETURN_V_MSG_E(drmDecryptor_ != nullptr, (int32_t)Status::ERROR_NO_MEMORY, "drmDecryptor is nullptr");
756 drmDecryptor_->SetDecryptionConfig(keySession, svpFlag);
757 return (int32_t)Status::OK;
758 }
759 #else
SetAudioDecryptionConfig(const sptr<DrmStandard::IMediaKeySessionService> & keySession,const bool svpFlag)760 int32_t MediaCodec::SetAudioDecryptionConfig(const sptr<DrmStandard::IMediaKeySessionService> &keySession,
761 const bool svpFlag)
762 {
763 MEDIA_LOG_I("MediaCodec::SetAudioDecryptionConfig, Not support");
764 (void)keySession;
765 (void)svpFlag;
766 return (int32_t)Status::OK;
767 }
768 #endif
769
ChangePlugin(const std::string & mime,bool isEncoder,const std::shared_ptr<Meta> & meta)770 Status MediaCodec::ChangePlugin(const std::string &mime, bool isEncoder, const std::shared_ptr<Meta> &meta)
771 {
772 Status ret = Status::OK;
773 Plugins::PluginType type;
774 if (isEncoder) {
775 type = Plugins::PluginType::AUDIO_ENCODER;
776 } else {
777 type = Plugins::PluginType::AUDIO_DECODER;
778 }
779 if (codecPlugin_ != nullptr) {
780 codecPlugin_->Release();
781 codecPlugin_ = nullptr;
782 }
783 codecPlugin_ = CreatePlugin(mime, type);
784
785 CHECK_AND_RETURN_RET_LOG(codecPlugin_ != nullptr, Status::ERROR_INVALID_PARAMETER, "createPlugin failed");
786 ret = codecPlugin_->SetParameter(meta);
787 MEDIA_LOG_I("codecPlugin SetParameter ret %{public}d", ret);
788 ret = codecPlugin_->Init();
789 MEDIA_LOG_I("codecPlugin Init ret %{public}d", ret);
790 ret = codecPlugin_->SetDataCallback(this);
791 MEDIA_LOG_I("codecPlugin SetDataCallback ret %{public}d", ret);
792
793 // discard undecoded data and unconsumed decoded data.
794 inputBufferQueueProducer_->Clear();
795 FALSE_RETURN_V_MSG_E(inputBufferQueue_ != nullptr, Status::ERROR_UNKNOWN, "inputBufferQueue_ is nullptr");
796 ClearInputBuffer();
797 inputBufferEosStatus_.store(0);
798 isOutputBufferAvailable_.store(true);
799
800 PrepareInputBufferQueue();
801 PrepareOutputBufferQueue();
802 if (state_ == CodecState::RUNNING) {
803 ret = codecPlugin_->Start();
804 MEDIA_LOG_I("codecPlugin Start ret %{public}d", ret);
805 }
806
807 return ret;
808 }
809
HandleOutputBuffer(uint32_t eosStatus)810 Status MediaCodec::HandleOutputBuffer(uint32_t eosStatus)
811 {
812 MEDIA_LOG_D("HandleOutputBuffer enter");
813 bool isBufferAvailable = false;
814 Status ret = HandleOutputBufferOnce(isBufferAvailable, eosStatus, true);
815 MEDIA_LOG_D("HandleOutputBuffer ret:%{public}d, isBufferAvailable:%{public}d", ret, isBufferAvailable);
816 return ret;
817 }
818
HandleOutputBufferOnce(bool & isBufferAvailable,uint32_t eosStatus,bool isSync)819 Status MediaCodec::HandleOutputBufferOnce(bool &isBufferAvailable, uint32_t eosStatus, bool isSync)
820 {
821 MediaAVCodec::AVCodecTrace traceHandleOutputBufferOnce("MediaCodec::HandleOutputBufferOnce");
822 Status ret = Status::OK;
823 std::shared_ptr<AVBuffer> emptyOutputBuffer;
824 AVBufferConfig avBufferConfig;
825 {
826 if (isSync) {
827 MediaAVCodec::AVCodecTrace traceRequestBuffer("MediaCodec::HandleOutputBufferOnce-RequestBuffer-sync");
828 do {
829 ret = outputBufferQueueProducer_->RequestBuffer(emptyOutputBuffer, avBufferConfig, TIME_OUT_MS);
830 } while (ret != Status::OK && state_ == CodecState::RUNNING);
831 } else {
832 MediaAVCodec::AVCodecTrace traceRequestBuffer("MediaCodec::HandleOutputBufferOnce-RequestBuffer-async");
833 ret = outputBufferQueueProducer_->RequestBuffer(emptyOutputBuffer, avBufferConfig, TIME_OUT_MS_INNER);
834 }
835 }
836 if (emptyOutputBuffer) {
837 emptyOutputBuffer->flag_ = eosStatus;
838 isBufferAvailable = true;
839 } else if (state_ != CodecState::RUNNING) {
840 return Status::OK;
841 } else {
842 return Status::ERROR_NULL_POINTER;
843 }
844 FALSE_RETURN_V_MSG_E(codecPlugin_ != nullptr, Status::ERROR_INVALID_STATE, "plugin is null");
845
846 {
847 MediaAVCodec::AVCodecTrace traceQueueOutputBuffer("MediaCodec::HandleOutputBufferOnce-QueueOutputBuffer");
848 ret = codecPlugin_->QueueOutputBuffer(emptyOutputBuffer);
849 }
850
851 if (ret == Status::ERROR_NOT_ENOUGH_DATA) {
852 MEDIA_LOG_D("HandleOutputBufferOnce QueueOutputBuffer ERROR_NOT_ENOUGH_DATA");
853 outputBufferQueueProducer_->PushBuffer(emptyOutputBuffer, false);
854 } else if (ret == Status::ERROR_AGAIN) {
855 MEDIA_LOG_D("HandleOutputBufferOnce The output data is not completely read, needs to be read again");
856 } else if (ret == Status::END_OF_STREAM) {
857 MEDIA_LOG_D("HandleOutputBufferOnce QueueOutputBuffer END_OF_STREAM");
858 } else if (ret != Status::OK) {
859 MEDIA_LOG_E("HandleOutputBufferOnce QueueOutputBuffer error");
860 outputBufferQueueProducer_->PushBuffer(emptyOutputBuffer, false);
861 }
862 return ret;
863 }
864
OnInputBufferDone(const std::shared_ptr<AVBuffer> & inputBuffer)865 void MediaCodec::OnInputBufferDone(const std::shared_ptr<AVBuffer> &inputBuffer)
866 {
867 MediaAVCodec::AVCodecTrace trace("MediaCodec::OnInputBufferDone");
868 Status ret = inputBufferQueueConsumer_->ReleaseBuffer(inputBuffer);
869 MEDIA_LOG_D("0x%{public}06" PRIXPTR " OnInputBufferDone, buffer->pts:" PUBLIC_LOG_D64,
870 FAKE_POINTER(this), inputBuffer->pts_);
871 FALSE_RETURN_MSG(ret == Status::OK, "OnInputBufferDone fail");
872 }
873
OnOutputBufferDone(const std::shared_ptr<AVBuffer> & outputBuffer)874 void MediaCodec::OnOutputBufferDone(const std::shared_ptr<AVBuffer> &outputBuffer)
875 {
876 MediaAVCodec::AVCodecTrace trace("MediaCodec::OnOutputBufferDone");
877 if (isDump_) {
878 DumpAVBufferToFile(DUMP_PARAM, dumpPrefix_ + DUMP_FILE_NAME, outputBuffer);
879 }
880 Status ret = outputBufferQueueProducer_->PushBuffer(outputBuffer, true);
881 auto realPtr = mediaCodecCallback_.lock();
882 if (realPtr != nullptr) {
883 realPtr->OnOutputBufferDone(outputBuffer);
884 }
885 MEDIA_LOG_D("0x%{public}06" PRIXPTR " OnOutputBufferDone, buffer->pts:" PUBLIC_LOG_D64,
886 FAKE_POINTER(this), outputBuffer->pts_);
887 FALSE_RETURN_MSG(ret == Status::OK, "OnOutputBufferDone fail");
888 }
889
ClearBufferQueue()890 void MediaCodec::ClearBufferQueue()
891 {
892 MEDIA_LOG_I("ClearBufferQueue called.");
893 if (inputBufferQueueProducer_ != nullptr) {
894 for (const auto &buffer : inputBufferVector_) {
895 inputBufferQueueProducer_->DetachBuffer(buffer);
896 }
897 inputBufferVector_.clear();
898 inputBufferQueueProducer_->SetQueueSize(0);
899 }
900 if (outputBufferQueueProducer_ != nullptr) {
901 for (const auto &buffer : outputBufferVector_) {
902 outputBufferQueueProducer_->DetachBuffer(buffer);
903 }
904 outputBufferVector_.clear();
905 outputBufferQueueProducer_->SetQueueSize(0);
906 }
907 }
908
ClearInputBuffer()909 void MediaCodec::ClearInputBuffer()
910 {
911 MediaAVCodec::AVCodecTrace trace("MediaCodec::ClearInputBuffer");
912 MEDIA_LOG_D("ClearInputBuffer enter");
913 if (!inputBufferQueueConsumer_) {
914 return;
915 }
916 std::shared_ptr<AVBuffer> filledInputBuffer;
917 Status ret = Status::OK;
918 while (ret == Status::OK) {
919 ret = inputBufferQueueConsumer_->AcquireBuffer(filledInputBuffer);
920 if (ret != Status::OK) {
921 MEDIA_LOG_I("clear input Buffer");
922 return;
923 }
924 inputBufferQueueConsumer_->ReleaseBuffer(filledInputBuffer);
925 }
926 }
927
OnEvent(const std::shared_ptr<Plugins::PluginEvent> event)928 void MediaCodec::OnEvent(const std::shared_ptr<Plugins::PluginEvent> event)
929 {
930 if (event->type != Plugins::PluginEventType::AUDIO_OUTPUT_FORMAT_CHANGED) {
931 return;
932 }
933
934 if (!isSupportAudioFormatChanged_) {
935 MEDIA_LOG_W("receive audio format changed but api version is low");
936 return;
937 }
938
939 auto realPtr = mediaCodecCallback_.lock();
940 if (realPtr != nullptr) {
941 std::shared_ptr<Meta> format = std::make_shared<Meta>(AnyCast<Meta>(event->param));
942 realPtr->OnOutputFormatChanged(format);
943 } else {
944 MEDIA_LOG_E("receive AUDIO_OUTPUT_FORMAT_CHANGED, but lock callback fail");
945 }
946 }
947
StateToString(CodecState state)948 std::string MediaCodec::StateToString(CodecState state)
949 {
950 std::map<CodecState, std::string> stateStrMap = {
951 {CodecState::UNINITIALIZED, " UNINITIALIZED"},
952 {CodecState::INITIALIZED, " INITIALIZED"},
953 {CodecState::FLUSHED, " FLUSHED"},
954 {CodecState::RUNNING, " RUNNING"},
955 {CodecState::INITIALIZING, " INITIALIZING"},
956 {CodecState::STARTING, " STARTING"},
957 {CodecState::STOPPING, " STOPPING"},
958 {CodecState::FLUSHING, " FLUSHING"},
959 {CodecState::RESUMING, " RESUMING"},
960 {CodecState::RELEASING, " RELEASING"},
961 };
962 return stateStrMap[state];
963 }
964
OnDumpInfo(int32_t fd)965 void MediaCodec::OnDumpInfo(int32_t fd)
966 {
967 MEDIA_LOG_D("MediaCodec::OnDumpInfo called.");
968 if (fd < 0) {
969 MEDIA_LOG_E("MediaCodec::OnDumpInfo fd is invalid.");
970 return;
971 }
972 std::string dumpString;
973 dumpString += "MediaCodec plugin name: " + codecPluginName_ + "\n";
974 dumpString += "MediaCodec buffer size is:" + std::to_string(inputBufferQueue_->GetQueueSize()) + "\n";
975 int ret = write(fd, dumpString.c_str(), dumpString.size());
976 if (ret < 0) {
977 MEDIA_LOG_E("MediaCodec::OnDumpInfo write failed.");
978 return;
979 }
980 }
981
GetApiVersion()982 uint32_t MediaCodec::GetApiVersion()
983 {
984 uint32_t apiVersion = INVALID_API_VERSION;
985 OHOS::sptr<OHOS::ISystemAbilityManager> systemAbilityManager =
986 OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
987 OHOS::sptr<OHOS::IRemoteObject> remoteObject =
988 systemAbilityManager->CheckSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
989 sptr<AppExecFwk::IBundleMgr> iBundleMgr = OHOS::iface_cast<AppExecFwk::IBundleMgr>(remoteObject);
990 if (iBundleMgr == nullptr) {
991 MEDIA_LOG_W("GetApiVersion IBundleMgr is nullptr");
992 return apiVersion;
993 }
994 AppExecFwk::BundleInfo bundleInfo;
995 if (iBundleMgr->GetBundleInfoForSelf(0, bundleInfo) == ERR_OK) {
996 apiVersion = bundleInfo.targetVersion % API_VERSION_MOD;
997 MEDIA_LOG_I("GetApiVersion targetVersion: %{public}u", bundleInfo.targetVersion);
998 } else {
999 MEDIA_LOG_W("GetApiVersion failed, call by SA or test maybe");
1000 }
1001 return apiVersion;
1002 }
1003
1004 } // namespace Media
1005 } // namespace OHOS
1006