• 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 "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> &parameter)
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> &parameter)
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