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