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