• 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 "plugin/plugin_manager_v2.h"
23 
24 namespace {
25 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_AUDIO, "MediaCodec" };
26 const std::string INPUT_BUFFER_QUEUE_NAME = "MediaCodecInputBufferQueue";
27 constexpr int32_t DEFAULT_BUFFER_NUM = 8;
28 constexpr int32_t TIME_OUT_MS = 50;
29 const std::string DUMP_PARAM = "a";
30 const std::string DUMP_FILE_NAME = "player_audio_decoder_output.pcm";
31 } // namespace
32 
33 namespace OHOS {
34 namespace Media {
35 class InputBufferAvailableListener : public IConsumerListener {
36 public:
InputBufferAvailableListener(MediaCodec * mediaCodec)37     explicit InputBufferAvailableListener(MediaCodec *mediaCodec)
38     {
39         mediaCodec_ = mediaCodec;
40     }
41 
OnBufferAvailable()42     void OnBufferAvailable() override
43     {
44         mediaCodec_->ProcessInputBuffer();
45     }
46 
47 private:
48     MediaCodec *mediaCodec_;
49 };
50 
MediaCodec()51 MediaCodec::MediaCodec()
52     : codecPlugin_(nullptr),
53       inputBufferQueue_(nullptr),
54       inputBufferQueueProducer_(nullptr),
55       inputBufferQueueConsumer_(nullptr),
56       outputBufferQueueProducer_(nullptr),
57       codecCallback_(nullptr),
58       mediaCodecCallback_(nullptr),
59       isEncoder_(false),
60       isSurfaceMode_(false),
61       isBufferMode_(false),
62       outputBufferCapacity_(0),
63       state_(CodecState::UNINITIALIZED)
64 {
65 }
66 
~MediaCodec()67 MediaCodec::~MediaCodec()
68 {
69     state_ = CodecState::UNINITIALIZED;
70     outputBufferCapacity_ = 0;
71     if (codecPlugin_) {
72         codecPlugin_ = nullptr;
73     }
74     if (inputBufferQueue_) {
75         inputBufferQueue_ = nullptr;
76     }
77     if (inputBufferQueueProducer_) {
78         inputBufferQueueProducer_ = nullptr;
79     }
80     if (inputBufferQueueConsumer_) {
81         inputBufferQueueConsumer_ = nullptr;
82     }
83     if (outputBufferQueueProducer_) {
84         outputBufferQueueProducer_ = nullptr;
85     }
86     if (codecCallback_) {
87         codecCallback_ = nullptr;
88     }
89     if (mediaCodecCallback_) {
90         mediaCodecCallback_ = nullptr;
91     }
92 }
93 
Init(const std::string & mime,bool isEncoder)94 int32_t MediaCodec::Init(const std::string &mime, bool isEncoder)
95 {
96     AutoLock lock(stateMutex_);
97     MediaAVCodec::AVCodecTrace trace("MediaCodec::Init");
98     MEDIA_LOG_I("Init enter, mime: " PUBLIC_LOG_S, mime.c_str());
99     if (state_ != CodecState::UNINITIALIZED) {
100         MEDIA_LOG_E("Init failed, state = %{public}s .", StateToString(state_).data());
101         return (int32_t)Status::ERROR_INVALID_STATE;
102     }
103     MEDIA_LOG_I("state from %{public}s to INITIALIZING", StateToString(state_).data());
104     state_ = CodecState::INITIALIZING;
105     Plugins::PluginType type;
106     if (isEncoder) {
107         type = Plugins::PluginType::AUDIO_ENCODER;
108     } else {
109         type = Plugins::PluginType::AUDIO_DECODER;
110     }
111     codecPlugin_ = CreatePlugin(mime, type);
112     if (codecPlugin_ != nullptr) {
113         MEDIA_LOG_I("codecPlugin_->Init()");
114         auto ret = codecPlugin_->Init();
115         FALSE_RETURN_V_MSG_E(ret == Status::OK, (int32_t)ret, "pluign init failed");
116         state_ = CodecState::INITIALIZED;
117     } else {
118         MEDIA_LOG_I("createPlugin failed");
119         return (int32_t)Status::ERROR_INVALID_PARAMETER;
120     }
121     return (int32_t)Status::OK;
122 }
123 
Init(const std::string & name)124 int32_t MediaCodec::Init(const std::string &name)
125 {
126     AutoLock lock(stateMutex_);
127     MEDIA_LOG_I("Init enter, name: " PUBLIC_LOG_S, name.c_str());
128     MediaAVCodec::AVCodecTrace trace("MediaCodec::Init");
129     if (state_ != CodecState::UNINITIALIZED) {
130         MEDIA_LOG_E("Init failed, state = %{public}s .", StateToString(state_).data());
131         return (int32_t)Status::ERROR_INVALID_STATE;
132     }
133     MEDIA_LOG_I("state from %{public}s to INITIALIZING", StateToString(state_).data());
134     state_ = CodecState::INITIALIZING;
135     auto plugin = Plugins::PluginManagerV2::Instance().CreatePluginByName(name);
136     FALSE_RETURN_V_MSG_E(plugin != nullptr, (int32_t)Status::ERROR_INVALID_PARAMETER, "create pluign failed");
137     codecPlugin_ = std::reinterpret_pointer_cast<Plugins::CodecPlugin>(plugin);
138     Status ret = codecPlugin_->Init();
139     FALSE_RETURN_V_MSG_E(ret == Status::OK, (int32_t)Status::ERROR_INVALID_PARAMETER, "pluign init failed");
140     state_ = CodecState::INITIALIZED;
141     return (int32_t)Status::OK;
142 }
143 
CreatePlugin(const std::string & mime,Plugins::PluginType pluginType)144 std::shared_ptr<Plugins::CodecPlugin> MediaCodec::CreatePlugin(const std::string &mime, Plugins::PluginType pluginType)
145 {
146     auto plugin = Plugins::PluginManagerV2::Instance().CreatePluginByMime(pluginType, mime);
147     if (plugin == nullptr) {
148         return nullptr;
149     }
150     return std::reinterpret_pointer_cast<Plugins::CodecPlugin>(plugin);
151 }
152 
Configure(const std::shared_ptr<Meta> & meta)153 int32_t MediaCodec::Configure(const std::shared_ptr<Meta> &meta)
154 {
155     MEDIA_LOG_I("MediaCodec::configure in");
156     AutoLock lock(stateMutex_);
157     MediaAVCodec::AVCodecTrace trace("MediaCodec::Configure");
158     FALSE_RETURN_V(state_ == CodecState::INITIALIZED, (int32_t)Status::ERROR_INVALID_STATE);
159     auto ret = codecPlugin_->SetParameter(meta);
160     FALSE_RETURN_V(ret == Status::OK, (int32_t)ret);
161     ret = codecPlugin_->SetDataCallback(this);
162     FALSE_RETURN_V(ret == Status::OK, (int32_t)ret);
163     state_ = CodecState::CONFIGURED;
164     return (int32_t)Status::OK;
165 }
166 
SetOutputBufferQueue(const sptr<AVBufferQueueProducer> & bufferQueueProducer)167 int32_t MediaCodec::SetOutputBufferQueue(const sptr<AVBufferQueueProducer> &bufferQueueProducer)
168 {
169     AutoLock lock(stateMutex_);
170     MediaAVCodec::AVCodecTrace trace("MediaCodec::SetOutputBufferQueue");
171     FALSE_RETURN_V(state_ == CodecState::INITIALIZED || state_ == CodecState::CONFIGURED,
172                    (int32_t)Status::ERROR_INVALID_STATE);
173     outputBufferQueueProducer_ = bufferQueueProducer;
174     isBufferMode_ = true;
175     return (int32_t)Status::OK;
176 }
177 
SetCodecCallback(const std::shared_ptr<CodecCallback> & codecCallback)178 int32_t MediaCodec::SetCodecCallback(const std::shared_ptr<CodecCallback> &codecCallback)
179 {
180     AutoLock lock(stateMutex_);
181     FALSE_RETURN_V(state_ == CodecState::INITIALIZED || state_ == CodecState::CONFIGURED,
182                    (int32_t)Status::ERROR_INVALID_STATE);
183     FALSE_RETURN_V_MSG_E(codecCallback != nullptr, (int32_t)Status::ERROR_INVALID_PARAMETER,
184                          "codecCallback is nullptr");
185     codecCallback_ = codecCallback;
186     auto ret = codecPlugin_->SetDataCallback(this);
187     FALSE_RETURN_V(ret == Status::OK, (int32_t)ret);
188     return (int32_t)Status::OK;
189 }
190 
SetCodecCallback(const std::shared_ptr<AudioBaseCodecCallback> & codecCallback)191 int32_t MediaCodec::SetCodecCallback(const std::shared_ptr<AudioBaseCodecCallback> &codecCallback)
192 {
193     AutoLock lock(stateMutex_);
194     FALSE_RETURN_V(state_ == CodecState::INITIALIZED || state_ == CodecState::CONFIGURED,
195                    (int32_t)Status::ERROR_INVALID_STATE);
196     FALSE_RETURN_V_MSG_E(codecCallback != nullptr, (int32_t)Status::ERROR_INVALID_PARAMETER,
197                          "codecCallback is nullptr");
198     mediaCodecCallback_ = codecCallback;
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     if (mediaCodecCallback_ != nullptr) {
519         mediaCodecCallback_->OnError(CodecErrorType::CODEC_DRM_DECRYTION_FAILED,
520             static_cast<int32_t>(Status::ERROR_DRM_DECRYPT_FAILED));
521     }
522 }
523 
PrepareInputBufferQueue()524 int32_t MediaCodec::PrepareInputBufferQueue()
525 {
526     MEDIA_LOG_I("PrepareInputBufferQueue enter");
527     std::vector<std::shared_ptr<AVBuffer>> inputBuffers;
528     MediaAVCodec::AVCodecTrace trace("MediaCodec::PrepareInputBufferQueue");
529     FALSE_RETURN_V_MSG_E(codecPlugin_ != nullptr, (int32_t)Status::ERROR_UNKNOWN, "codecPlugin_ is nullptr");
530     auto ret = codecPlugin_->GetInputBuffers(inputBuffers);
531     FALSE_RETURN_V_MSG_E(ret == Status::OK, (int32_t)ret, "pluign getInputBuffers failed");
532     if (inputBuffers.empty()) {
533         ret = AttachBufffer();
534         if (ret != Status::OK) {
535             MEDIA_LOG_E("GetParameter failed");
536             return (int32_t)ret;
537         }
538     } else {
539         if (inputBufferQueue_ == nullptr) {
540             inputBufferQueue_ =
541                 AVBufferQueue::Create(inputBuffers.size(), MemoryType::HARDWARE_MEMORY, INPUT_BUFFER_QUEUE_NAME);
542         }
543         FALSE_RETURN_V_MSG_E(inputBufferQueue_ != nullptr, (int32_t)Status::ERROR_UNKNOWN,
544                              "inputBufferQueue_ is nullptr");
545         inputBufferQueueProducer_ = inputBufferQueue_->GetProducer();
546         for (uint32_t i = 0; i < inputBuffers.size(); i++) {
547             inputBufferQueueProducer_->AttachBuffer(inputBuffers[i], false);
548             inputBufferVector_.push_back(inputBuffers[i]);
549         }
550     }
551     FALSE_RETURN_V_MSG_E(inputBufferQueue_ != nullptr, (int32_t)Status::ERROR_UNKNOWN, "inputBufferQueue_ is nullptr");
552     inputBufferQueueConsumer_ = inputBufferQueue_->GetConsumer();
553     sptr<IConsumerListener> listener = new InputBufferAvailableListener(this);
554     FALSE_RETURN_V_MSG_E(inputBufferQueueConsumer_ != nullptr, (int32_t)Status::ERROR_UNKNOWN,
555                          "inputBufferQueueConsumer_ is nullptr");
556     inputBufferQueueConsumer_->SetBufferAvailableListener(listener);
557     return (int32_t)ret;
558 }
559 
PrepareOutputBufferQueue()560 int32_t MediaCodec::PrepareOutputBufferQueue()
561 {
562     MEDIA_LOG_I("PrepareOutputBufferQueue enter");
563     std::vector<std::shared_ptr<AVBuffer>> outputBuffers;
564     MediaAVCodec::AVCodecTrace trace("MediaCodec::PrepareOutputBufferQueue");
565     FALSE_RETURN_V_MSG_E(codecPlugin_ != nullptr, (int32_t)Status::ERROR_INVALID_STATE, "codecPlugin_ is nullptr");
566     auto ret = codecPlugin_->GetOutputBuffers(outputBuffers);
567     FALSE_RETURN_V_MSG_E(ret == Status::OK, (int32_t)ret, "GetOutputBuffers failed");
568     FALSE_RETURN_V_MSG_E(outputBufferQueueProducer_ != nullptr, (int32_t)Status::ERROR_INVALID_STATE,
569                          "outputBufferQueueProducer_ is nullptr");
570     if (outputBuffers.empty()) {
571         int outputBufferNum = 30;
572         std::shared_ptr<Meta> outputBufferConfig = std::make_shared<Meta>();
573         ret = codecPlugin_->GetParameter(outputBufferConfig);
574         FALSE_RETURN_V_MSG_E(ret == Status::OK, (int32_t)ret, "GetParameter failed");
575         FALSE_RETURN_V_MSG_E(outputBufferConfig != nullptr, (int32_t)Status::ERROR_INVALID_STATE,
576                              "outputBufferConfig is nullptr");
577         FALSE_RETURN_V(outputBufferConfig->Get<Tag::AUDIO_MAX_OUTPUT_SIZE>(outputBufferCapacity_),
578                        (int32_t)Status::ERROR_INVALID_PARAMETER);
579         for (int i = 0; i < outputBufferNum; i++) {
580             auto avAllocator = AVAllocatorFactory::CreateSharedAllocator(MemoryFlag::MEMORY_READ_WRITE);
581             std::shared_ptr<AVBuffer> outputBuffer = AVBuffer::CreateAVBuffer(avAllocator, outputBufferCapacity_);
582             FALSE_RETURN_V_MSG_E(outputBuffer != nullptr, (int32_t)Status::ERROR_INVALID_STATE,
583                                  "outputBuffer is nullptr");
584             if (outputBufferQueueProducer_->AttachBuffer(outputBuffer, false) == Status::OK) {
585                 MEDIA_LOG_D("Attach output buffer. index: %{public}d, bufferId: %{public}" PRIu64, i,
586                             outputBuffer->GetUniqueId());
587                 outputBufferVector_.push_back(outputBuffer);
588             }
589         }
590     } else {
591         for (uint32_t i = 0; i < outputBuffers.size(); i++) {
592             if (outputBufferQueueProducer_->AttachBuffer(outputBuffers[i], false) == Status::OK) {
593                 MEDIA_LOG_D("Attach output buffer. index: %{public}d, bufferId: %{public}" PRIu64, i,
594                             outputBuffers[i]->GetUniqueId());
595                 outputBufferVector_.push_back(outputBuffers[i]);
596             }
597         }
598     }
599     FALSE_RETURN_V_MSG_E(outputBufferVector_.size() > 0, (int32_t)Status::ERROR_INVALID_STATE, "Attach no buffer");
600     return (int32_t)ret;
601 }
602 
ProcessInputBuffer()603 void MediaCodec::ProcessInputBuffer()
604 {
605     MEDIA_LOG_D("ProcessInputBuffer enter");
606     MediaAVCodec::AVCodecTrace trace("MediaCodec::ProcessInputBuffer");
607     Status ret;
608     uint32_t eosStatus = 0;
609     std::shared_ptr<AVBuffer> filledInputBuffer;
610     if (state_ != CodecState::RUNNING) {
611         MEDIA_LOG_E("status changed, current status is not running in ProcessInputBuffer");
612         return;
613     }
614     ret = inputBufferQueueConsumer_->AcquireBuffer(filledInputBuffer);
615     if (ret != Status::OK) {
616         MEDIA_LOG_E("ProcessInputBuffer AcquireBuffer fail");
617         return;
618     }
619     if (state_ != CodecState::RUNNING) {
620         MEDIA_LOG_D("ProcessInputBuffer ReleaseBuffer name:MediaCodecInputBufferQueue");
621         inputBufferQueueConsumer_->ReleaseBuffer(filledInputBuffer);
622         return;
623     }
624     const int8_t RETRY = 3; // max retry count is 3
625     int8_t retryCount = 0;
626     do {
627         if (drmDecryptor_ != nullptr) {
628             ret = DrmAudioCencDecrypt(filledInputBuffer);
629             if (ret != Status::OK) {
630                 HandleAudioCencDecryptError();
631                 break;
632             }
633         }
634 
635         ret = codecPlugin_->QueueInputBuffer(filledInputBuffer);
636         if (ret != Status::OK) {
637             retryCount++;
638             continue;
639         }
640     } while (ret != Status::OK && retryCount < RETRY);
641 
642     if (ret != Status::OK) {
643         inputBufferQueueConsumer_->ReleaseBuffer(filledInputBuffer);
644         MEDIA_LOG_E("Plugin queueInputBuffer failed.");
645         return;
646     }
647     eosStatus = filledInputBuffer->flag_;
648     do {
649         ret = HandleOutputBuffer(eosStatus);
650     } while (ret == Status::ERROR_AGAIN);
651 }
652 
653 #ifdef SUPPORT_DRM
SetAudioDecryptionConfig(const sptr<DrmStandard::IMediaKeySessionService> & keySession,const bool svpFlag)654 int32_t MediaCodec::SetAudioDecryptionConfig(const sptr<DrmStandard::IMediaKeySessionService> &keySession,
655     const bool svpFlag)
656 {
657     MEDIA_LOG_I("MediaCodec::SetAudioDecryptionConfig");
658     if (drmDecryptor_ == nullptr) {
659         drmDecryptor_ = std::make_shared<MediaAVCodec::CodecDrmDecrypt>();
660     }
661     FALSE_RETURN_V_MSG_E(drmDecryptor_ != nullptr, (int32_t)Status::ERROR_NO_MEMORY, "drmDecryptor is nullptr");
662     drmDecryptor_->SetDecryptionConfig(keySession, svpFlag);
663     return (int32_t)Status::OK;
664 }
665 #else
SetAudioDecryptionConfig(const sptr<DrmStandard::IMediaKeySessionService> & keySession,const bool svpFlag)666 int32_t MediaCodec::SetAudioDecryptionConfig(const sptr<DrmStandard::IMediaKeySessionService> &keySession,
667     const bool svpFlag)
668 {
669     MEDIA_LOG_I("MediaCodec::SetAudioDecryptionConfig, Not support");
670     (void)keySession;
671     (void)svpFlag;
672     return (int32_t)Status::OK;
673 }
674 #endif
675 
ChangePlugin(const std::string & mime,bool isEncoder,const std::shared_ptr<Meta> & meta)676 Status MediaCodec::ChangePlugin(const std::string &mime, bool isEncoder, const std::shared_ptr<Meta> &meta)
677 {
678     Status ret = Status::OK;
679     Plugins::PluginType type;
680     if (isEncoder) {
681         type = Plugins::PluginType::AUDIO_ENCODER;
682     } else {
683         type = Plugins::PluginType::AUDIO_DECODER;
684     }
685     if (codecPlugin_ != nullptr) {
686         codecPlugin_->Release();
687         codecPlugin_ = nullptr;
688     }
689     codecPlugin_ = CreatePlugin(mime, type);
690     if (codecPlugin_ != nullptr) {
691         ret = codecPlugin_->SetParameter(meta);
692         MEDIA_LOG_I("codecPlugin SetParameter ret %{public}d", ret);
693         ret = codecPlugin_->Init();
694         MEDIA_LOG_I("codecPlugin Init ret %{public}d", ret);
695         ret = codecPlugin_->SetDataCallback(this);
696         MEDIA_LOG_I("codecPlugin SetDataCallback ret %{public}d", ret);
697         PrepareInputBufferQueue();
698         PrepareOutputBufferQueue();
699         if (state_ == CodecState::RUNNING) {
700             ret = codecPlugin_->Start();
701             MEDIA_LOG_I("codecPlugin Start ret %{public}d", ret);
702         }
703     } else {
704         MEDIA_LOG_I("createPlugin failed");
705         return Status::ERROR_INVALID_PARAMETER;
706     }
707     return ret;
708 }
709 
HandleOutputBuffer(uint32_t eosStatus)710 Status MediaCodec::HandleOutputBuffer(uint32_t eosStatus)
711 {
712     MEDIA_LOG_D("HandleOutputBuffer enter");
713     Status ret = Status::OK;
714     std::shared_ptr<AVBuffer> emptyOutputBuffer;
715     AVBufferConfig avBufferConfig;
716     do {
717         ret = outputBufferQueueProducer_->RequestBuffer(emptyOutputBuffer, avBufferConfig, TIME_OUT_MS);
718     } while (ret != Status::OK && state_ == CodecState::RUNNING);
719     if (emptyOutputBuffer) {
720         emptyOutputBuffer->flag_ = eosStatus;
721     } else if (state_ != CodecState::RUNNING) {
722         return Status::OK;
723     } else {
724         return Status::ERROR_NULL_POINTER;
725     }
726     FALSE_RETURN_V_MSG_E(codecPlugin_ != nullptr, Status::ERROR_INVALID_STATE, "plugin is null");
727     ret = codecPlugin_->QueueOutputBuffer(emptyOutputBuffer);
728     if (ret == Status::ERROR_NOT_ENOUGH_DATA) {
729         MEDIA_LOG_D("QueueOutputBuffer ERROR_NOT_ENOUGH_DATA");
730         outputBufferQueueProducer_->PushBuffer(emptyOutputBuffer, false);
731     } else if (ret == Status::ERROR_AGAIN) {
732         MEDIA_LOG_D("The output data is not completely read, needs to be read again");
733     } else if (ret == Status::END_OF_STREAM) {
734         MEDIA_LOG_D("HandleOutputBuffer END_OF_STREAM");
735     } else if (ret != Status::OK) {
736         MEDIA_LOG_E("QueueOutputBuffer error");
737         outputBufferQueueProducer_->PushBuffer(emptyOutputBuffer, false);
738     }
739     return ret;
740 }
741 
OnInputBufferDone(const std::shared_ptr<AVBuffer> & inputBuffer)742 void MediaCodec::OnInputBufferDone(const std::shared_ptr<AVBuffer> &inputBuffer)
743 {
744     MediaAVCodec::AVCodecTrace trace("MediaCodec::OnInputBufferDone");
745     Status ret = inputBufferQueueConsumer_->ReleaseBuffer(inputBuffer);
746     MEDIA_LOG_D("0x%{public}06" PRIXPTR " OnInputBufferDone, buffer->pts" PUBLIC_LOG_D64,
747         FAKE_POINTER(this), inputBuffer->pts_);
748     FALSE_RETURN_MSG(ret == Status::OK, "OnInputBufferDone fail");
749 }
750 
OnOutputBufferDone(const std::shared_ptr<AVBuffer> & outputBuffer)751 void MediaCodec::OnOutputBufferDone(const std::shared_ptr<AVBuffer> &outputBuffer)
752 {
753     MediaAVCodec::AVCodecTrace trace("MediaCodec::OnOutputBufferDone");
754     if (isDump_) {
755         DumpAVBufferToFile(DUMP_PARAM, dumpPrefix_ + DUMP_FILE_NAME, outputBuffer);
756     }
757     Status ret = outputBufferQueueProducer_->PushBuffer(outputBuffer, true);
758     if (mediaCodecCallback_) {
759         mediaCodecCallback_->OnOutputBufferDone(outputBuffer);
760     }
761     MEDIA_LOG_D("0x%{public}06" PRIXPTR " OnOutputBufferDone, buffer->pts" PUBLIC_LOG_D64,
762         FAKE_POINTER(this), outputBuffer->pts_);
763     FALSE_RETURN_MSG(ret == Status::OK, "OnOutputBufferDone fail");
764 }
765 
ClearBufferQueue()766 void MediaCodec::ClearBufferQueue()
767 {
768     MEDIA_LOG_I("ClearBufferQueue called.");
769     if (inputBufferQueueProducer_ != nullptr) {
770         for (const auto &buffer : inputBufferVector_) {
771             inputBufferQueueProducer_->DetachBuffer(buffer);
772         }
773         inputBufferVector_.clear();
774         inputBufferQueueProducer_->SetQueueSize(0);
775     }
776     if (outputBufferQueueProducer_ != nullptr) {
777         for (const auto &buffer : outputBufferVector_) {
778             outputBufferQueueProducer_->DetachBuffer(buffer);
779         }
780         outputBufferVector_.clear();
781         outputBufferQueueProducer_->SetQueueSize(0);
782     }
783 }
784 
ClearInputBuffer()785 void MediaCodec::ClearInputBuffer()
786 {
787     MediaAVCodec::AVCodecTrace trace("MediaCodec::ClearInputBuffer");
788     MEDIA_LOG_D("ClearInputBuffer enter");
789     if (!inputBufferQueueConsumer_) {
790         return;
791     }
792     std::shared_ptr<AVBuffer> filledInputBuffer;
793     Status ret = Status::OK;
794     while (ret == Status::OK) {
795         ret = inputBufferQueueConsumer_->AcquireBuffer(filledInputBuffer);
796         if (ret != Status::OK) {
797             MEDIA_LOG_I("clear input Buffer");
798             return;
799         }
800         inputBufferQueueConsumer_->ReleaseBuffer(filledInputBuffer);
801     }
802 }
803 
OnEvent(const std::shared_ptr<Plugins::PluginEvent> event)804 void MediaCodec::OnEvent(const std::shared_ptr<Plugins::PluginEvent> event) {}
805 
StateToString(CodecState state)806 std::string MediaCodec::StateToString(CodecState state)
807 {
808     std::map<CodecState, std::string> stateStrMap = {
809         {CodecState::UNINITIALIZED, " UNINITIALIZED"},
810         {CodecState::INITIALIZED, " INITIALIZED"},
811         {CodecState::FLUSHED, " FLUSHED"},
812         {CodecState::RUNNING, " RUNNING"},
813         {CodecState::INITIALIZING, " INITIALIZING"},
814         {CodecState::STARTING, " STARTING"},
815         {CodecState::STOPPING, " STOPPING"},
816         {CodecState::FLUSHING, " FLUSHING"},
817         {CodecState::RESUMING, " RESUMING"},
818         {CodecState::RELEASING, " RELEASING"},
819     };
820     return stateStrMap[state];
821 }
822 
OnDumpInfo(int32_t fd)823 void MediaCodec::OnDumpInfo(int32_t fd)
824 {
825     MEDIA_LOG_D("MediaCodec::OnDumpInfo called.");
826     if (fd < 0) {
827         MEDIA_LOG_E("MediaCodec::OnDumpInfo fd is invalid.");
828         return;
829     }
830     std::string dumpString;
831     dumpString += "MediaCodec plugin name: " + codecPluginName_ + "\n";
832     dumpString += "MediaCodec buffer size is:" + std::to_string(inputBufferQueue_->GetQueueSize()) + "\n";
833     int ret = write(fd, dumpString.c_str(), dumpString.size());
834     if (ret < 0) {
835         MEDIA_LOG_E("MediaCodec::OnDumpInfo write failed.");
836         return;
837     }
838 }
839 } // namespace Media
840 } // namespace OHOS
841