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