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