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> ¶meter) 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> ¶meter) 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