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