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