• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2025 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 <iostream>
18 #include <sstream>
19 #include <ctime>
20 #include <fstream>
21 #include "avcodec_common.h"
22 #include "common/log.h"
23 #include "osal/task/autolock.h"
24 #include "plugin/plugin_manager_v2.h"
25 #include "avcodec_log.h"
26 #include "osal/utils/dump_buffer.h"
27 #include "avcodec_trace.h"
28 #include "bundle_mgr_interface.h"
29 #include "iservice_registry.h"
30 #include "system_ability_definition.h"
31 #include "param_wrapper.h"
32 
33 #ifdef SUPPORT_DRM
34 #include "imedia_key_session_service.h"
35 #endif
36 
37 namespace {
38 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_AUDIO, "MediaCodec" };
39 const std::string INPUT_BUFFER_QUEUE_NAME = "MediaCodecInputBufferQueue";
40 constexpr int8_t RETRY = 3; // max retry count is 3
41 constexpr int32_t DEFAULT_BUFFER_NUM = 8;
42 constexpr int32_t TIME_OUT_MS = 50;
43 constexpr int32_t TIME_OUT_MS_INNER = 1;
44 constexpr uint32_t API_SUPPORT_AUDIO_FORMAT_CHANGED = 15;
45 constexpr uint32_t INVALID_API_VERSION = 0;
46 constexpr uint32_t API_VERSION_MOD = 1000;
47 const std::string DUMP_PARAM = "a";
48 const std::string DUMP_FILE_NAME = "player_audio_decoder_output.pcm";
49 const std::string DUMP_IO_LABLE = "sys.media.AVCodec.dump.enable";
50 } // namespace
51 
52 namespace OHOS {
53 namespace Media {
54 class InputBufferAvailableListener : public IConsumerListener {
55 public:
InputBufferAvailableListener(std::shared_ptr<MediaCodec> mediaCodec)56     explicit InputBufferAvailableListener(std::shared_ptr<MediaCodec> mediaCodec)
57     {
58         mediaCodec_ = mediaCodec;
59     }
60 
OnBufferAvailable()61     void OnBufferAvailable() override
62     {
63         auto realPtr = mediaCodec_.lock();
64         if (realPtr != nullptr) {
65             realPtr->ProcessInputBuffer();
66         } else {
67             MEDIA_LOG_W("mediacodec was released, can not process input buffer");
68         }
69     }
70 
71 private:
72     std::weak_ptr<MediaCodec> mediaCodec_;
73 };
74 
MediaCodec()75 MediaCodec::MediaCodec()
76     : codecPlugin_(nullptr),
77       inputBufferQueue_(nullptr),
78       inputBufferQueueProducer_(nullptr),
79       inputBufferQueueConsumer_(nullptr),
80       outputBufferQueueProducer_(nullptr),
81       isEncoder_(false),
82       isSurfaceMode_(false),
83       isBufferMode_(false),
84       outputBufferCapacity_(0),
85       state_(CodecState::UNINITIALIZED)
86 {
87 }
88 
~MediaCodec()89 MediaCodec::~MediaCodec()
90 {
91     state_ = CodecState::UNINITIALIZED;
92     outputBufferCapacity_ = 0;
93     if (codecPlugin_) {
94         codecPlugin_ = nullptr;
95     }
96     if (inputBufferQueue_) {
97         inputBufferQueue_ = nullptr;
98     }
99     if (inputBufferQueueProducer_) {
100         inputBufferQueueProducer_ = nullptr;
101     }
102     if (inputBufferQueueConsumer_) {
103         inputBufferQueueConsumer_ = nullptr;
104     }
105     if (outputBufferQueueProducer_) {
106         outputBufferQueueProducer_ = nullptr;
107     }
108 }
109 
Init(const std::string & mime,bool isEncoder)110 int32_t MediaCodec::Init(const std::string &mime, bool isEncoder)
111 {
112     AutoLock lock(stateMutex_);
113     MediaAVCodec::AVCodecTrace trace("MediaCodec::Init");
114     OHOS::system::GetStringParameter(DUMP_IO_LABLE, dumpIOEnable, "false");
115     MEDIA_LOG_I("Init enter, mime: " PUBLIC_LOG_S, mime.c_str());
116     if (state_ != CodecState::UNINITIALIZED) {
117         MEDIA_LOG_E("Init failed, state = %{public}s .", StateToString(state_).data());
118         return (int32_t)Status::ERROR_INVALID_STATE;
119     }
120     MEDIA_LOG_I("state from %{public}s to INITIALIZING", StateToString(state_).data());
121     state_ = CodecState::INITIALIZING;
122     Plugins::PluginType type;
123     if (isEncoder) {
124         type = Plugins::PluginType::AUDIO_ENCODER;
125     } else {
126         type = Plugins::PluginType::AUDIO_DECODER;
127     }
128     codecPlugin_ = CreatePlugin(mime, type);
129     if (codecPlugin_ != nullptr) {
130         MEDIA_LOG_I("codecPlugin_->Init()");
131         auto ret = codecPlugin_->Init();
132         FALSE_RETURN_V_MSG_E(ret == Status::OK, (int32_t)ret, "pluign init failed");
133         state_ = CodecState::INITIALIZED;
134     } else {
135         MEDIA_LOG_I("createPlugin failed");
136         state_ = CodecState::UNINITIALIZED;
137         return (int32_t)Status::ERROR_INVALID_PARAMETER;
138     }
139     return (int32_t)Status::OK;
140 }
141 
Init(const std::string & name)142 int32_t MediaCodec::Init(const std::string &name)
143 {
144     AutoLock lock(stateMutex_);
145     OHOS::system::GetStringParameter(DUMP_IO_LABLE, dumpIOEnable, "false");
146     MEDIA_LOG_I("Init enter, name: " PUBLIC_LOG_S, name.c_str());
147     MediaAVCodec::AVCodecTrace trace("MediaCodec::Init");
148     if (state_ != CodecState::UNINITIALIZED) {
149         MEDIA_LOG_E("Init failed, state = %{public}s .", StateToString(state_).data());
150         return (int32_t)Status::ERROR_INVALID_STATE;
151     }
152     MEDIA_LOG_I("state from %{public}s to INITIALIZING", StateToString(state_).data());
153     state_ = CodecState::INITIALIZING;
154     auto plugin = Plugins::PluginManagerV2::Instance().CreatePluginByName(name);
155     if (plugin == nullptr) {
156         MEDIA_LOG_E("create pluign failed");
157         state_ = CodecState::UNINITIALIZED;
158         return (int32_t)Status::ERROR_INVALID_PARAMETER;
159     }
160     codecPlugin_ = std::reinterpret_pointer_cast<Plugins::CodecPlugin>(plugin);
161     if (codecPlugin_->Init() != Status::OK) {
162         MEDIA_LOG_E("pluign init failed");
163         state_ = CodecState::UNINITIALIZED;
164         return (int32_t)Status::ERROR_INVALID_PARAMETER;
165     }
166     state_ = CodecState::INITIALIZED;
167     return (int32_t)Status::OK;
168 }
169 
CreatePlugin(const std::string & mime,Plugins::PluginType pluginType)170 std::shared_ptr<Plugins::CodecPlugin> MediaCodec::CreatePlugin(const std::string &mime, Plugins::PluginType pluginType)
171 {
172     auto plugin = Plugins::PluginManagerV2::Instance().CreatePluginByMime(pluginType, mime);
173     if (plugin == nullptr) {
174         return nullptr;
175     }
176     return std::reinterpret_pointer_cast<Plugins::CodecPlugin>(plugin);
177 }
178 
IODump(const std::shared_ptr<Meta> & meta)179 void MediaCodec::IODump(const std::shared_ptr<Meta> &meta)
180 {
181     std::time_t t = std::time(nullptr);
182     std::tm tm = *std::localtime(&t);
183 
184     std::ostringstream common;
185     common << "/data/media/";
186     common << std::put_time(&tm, "%H%M%S");
187     common << "_" << reinterpret_cast<void*>(this);
188 
189     int32_t channels = 0;
190     int32_t sampleRate = 0;
191     meta->GetData(Tag::AUDIO_SAMPLE_RATE, sampleRate);
192     common << "_" << sampleRate;
193     meta->GetData(Tag::AUDIO_CHANNEL_COUNT, channels);
194     common << "_" << channels;
195 
196     std::ostringstream inputStr;
197     std::ostringstream outputStr;
198     inputStr << common.str() << "_input.bin";
199     outputStr << common.str() << "_output.bin";
200 
201     dumpDataInputFs_ = std::make_shared<std::ofstream>(inputStr.str(), std::ios::binary);
202     dumpDataOutputFs_ = std::make_shared<std::ofstream>(outputStr.str(), std::ios::binary);
203 }
204 
Configure(const std::shared_ptr<Meta> & meta)205 int32_t MediaCodec::Configure(const std::shared_ptr<Meta> &meta)
206 {
207     MEDIA_LOG_I("MediaCodec::configure in");
208     AutoLock lock(stateMutex_);
209     MediaAVCodec::AVCodecTrace trace("MediaCodec::Configure");
210     if (dumpIOEnable == "true") {
211         IODump(meta);
212         MEDIA_LOG_I("IODump in");
213     }
214     FALSE_RETURN_V(state_ == CodecState::INITIALIZED, (int32_t)Status::ERROR_INVALID_STATE);
215     auto ret = codecPlugin_->SetParameter(meta);
216     FALSE_RETURN_V(ret == Status::OK, (int32_t)ret);
217     ret = codecPlugin_->SetDataCallback(this);
218     FALSE_RETURN_V(ret == Status::OK, (int32_t)ret);
219     state_ = CodecState::CONFIGURED;
220     return (int32_t)Status::OK;
221 }
222 
SetOutputBufferQueue(const sptr<AVBufferQueueProducer> & bufferQueueProducer)223 int32_t MediaCodec::SetOutputBufferQueue(const sptr<AVBufferQueueProducer> &bufferQueueProducer)
224 {
225     AutoLock lock(stateMutex_);
226     MediaAVCodec::AVCodecTrace trace("MediaCodec::SetOutputBufferQueue");
227     FALSE_RETURN_V(state_ == CodecState::INITIALIZED || state_ == CodecState::CONFIGURED,
228                    (int32_t)Status::ERROR_INVALID_STATE);
229     outputBufferQueueProducer_ = bufferQueueProducer;
230     isBufferMode_ = true;
231     return (int32_t)Status::OK;
232 }
233 
SetCodecCallback(const std::shared_ptr<CodecCallback> & codecCallback)234 int32_t MediaCodec::SetCodecCallback(const std::shared_ptr<CodecCallback> &codecCallback)
235 {
236     AutoLock lock(stateMutex_);
237     FALSE_RETURN_V(state_ == CodecState::INITIALIZED || state_ == CodecState::CONFIGURED,
238                    (int32_t)Status::ERROR_INVALID_STATE);
239     FALSE_RETURN_V_MSG_E(codecCallback != nullptr, (int32_t)Status::ERROR_INVALID_PARAMETER,
240                          "codecCallback is nullptr");
241     codecCallback_ = codecCallback;
242     auto ret = codecPlugin_->SetDataCallback(this);
243     FALSE_RETURN_V(ret == Status::OK, (int32_t)ret);
244     return (int32_t)Status::OK;
245 }
246 
SetCodecCallback(const std::shared_ptr<AudioBaseCodecCallback> & codecCallback)247 int32_t MediaCodec::SetCodecCallback(const std::shared_ptr<AudioBaseCodecCallback> &codecCallback)
248 {
249     AutoLock lock(stateMutex_);
250     FALSE_RETURN_V(state_ == CodecState::INITIALIZED || state_ == CodecState::CONFIGURED,
251                    (int32_t)Status::ERROR_INVALID_STATE);
252     FALSE_RETURN_V_MSG_E(codecCallback != nullptr, (int32_t)Status::ERROR_INVALID_PARAMETER,
253                          "codecCallback is nullptr");
254     mediaCodecCallback_ = codecCallback;
255     uint32_t apiVersion = GetApiVersion();
256     isSupportAudioFormatChanged_ =
257         ((apiVersion == INVALID_API_VERSION) || (apiVersion >= API_SUPPORT_AUDIO_FORMAT_CHANGED));
258     return (int32_t)Status::OK;
259 }
260 
SetOutputSurface(sptr<Surface> surface)261 int32_t MediaCodec::SetOutputSurface(sptr<Surface> surface)
262 {
263     AutoLock lock(stateMutex_);
264     FALSE_RETURN_V(state_ == CodecState::INITIALIZED || state_ == CodecState::CONFIGURED,
265                    (int32_t)Status::ERROR_INVALID_STATE);
266     isSurfaceMode_ = true;
267     return (int32_t)Status::OK;
268 }
269 
Prepare()270 int32_t MediaCodec::Prepare()
271 {
272     MEDIA_LOG_I("Prepare enter");
273     AutoLock lock(stateMutex_);
274     MediaAVCodec::AVCodecTrace trace("MediaCodec::Prepare");
275     FALSE_RETURN_V_MSG_W(state_ != CodecState::FLUSHED, (int32_t)Status::ERROR_AGAIN,
276         "state is flushed, no need prepare");
277     FALSE_RETURN_V(state_ != CodecState::PREPARED, (int32_t)Status::OK);
278     FALSE_RETURN_V(state_ == CodecState::CONFIGURED,
279         (int32_t)Status::ERROR_INVALID_STATE);
280     if (isBufferMode_ && isSurfaceMode_) {
281         MEDIA_LOG_E("state error");
282         return (int32_t)Status::ERROR_UNKNOWN;
283     }
284     outputBufferCapacity_ = 0;
285     auto ret = (int32_t)PrepareInputBufferQueue();
286     CHECK_AND_RETURN_RET_LOG(ret == (int32_t)Status::OK, (int32_t)ret, "PrepareInputBufferQueue failed");
287     ret = (int32_t)PrepareOutputBufferQueue();
288     CHECK_AND_RETURN_RET_LOG(ret == (int32_t)Status::OK, (int32_t)ret, "PrepareOutputBufferQueue failed");
289     state_ = CodecState::PREPARED;
290     MEDIA_LOG_I("Prepare, ret = %{public}d", (int32_t)ret);
291     return (int32_t)Status::OK;
292 }
293 
GetInputBufferQueue()294 sptr<AVBufferQueueProducer> MediaCodec::GetInputBufferQueue()
295 {
296     AutoLock lock(stateMutex_);
297     FALSE_RETURN_V(state_ == CodecState::PREPARED, sptr<AVBufferQueueProducer>());
298     CHECK_AND_RETURN_RET_LOG(!isSurfaceMode_, nullptr, "GetInputBufferQueue isSurfaceMode_");
299     isBufferMode_ = true;
300     return inputBufferQueueProducer_;
301 }
302 
GetInputBufferQueueConsumer()303 sptr<AVBufferQueueConsumer> MediaCodec::GetInputBufferQueueConsumer()
304 {
305     AutoLock lock(stateMutex_);
306     // Case: to enable to set listener to input bufferqueue consumer. i.e. input bufferqueue updating by ChangePlugin.
307     FALSE_RETURN_V(state_ == CodecState::PREPARED || state_ == CodecState::RUNNING ||
308                    state_ == CodecState::FLUSHED || state_ == CodecState::END_OF_STREAM, sptr<AVBufferQueueConsumer>());
309     CHECK_AND_RETURN_RET_LOG(!isSurfaceMode_, nullptr, "GetInputBufferQueueConsumer isSurfaceMode_");
310     isBufferMode_ = true;
311     return inputBufferQueueConsumer_;
312 }
313 
GetOutputBufferQueueProducer()314 sptr<AVBufferQueueProducer> MediaCodec::GetOutputBufferQueueProducer()
315 {
316     AutoLock lock(stateMutex_);
317     // Case: to enable to set listener to output bufferqueue producer. i.e. output bufferqueue updating by ChangePlugin.
318     FALSE_RETURN_V(state_ == CodecState::PREPARED || state_ == CodecState::RUNNING ||
319                    state_ == CodecState::FLUSHED || state_ == CodecState::END_OF_STREAM, sptr<AVBufferQueueProducer>());
320     CHECK_AND_RETURN_RET_LOG(!isSurfaceMode_, nullptr, "GetOutputBufferQueueProducer isSurfaceMode_");
321 
322     return outputBufferQueueProducer_;
323 }
324 
ProcessInputBufferInner(bool isTriggeredByOutPort,bool isFlushed)325 void MediaCodec::ProcessInputBufferInner(bool isTriggeredByOutPort, bool isFlushed)
326 {
327     uint32_t bufferStatus = static_cast<uint32_t>(InOutPortBufferStatus::INIT_IGNORE_RET);
328     ProcessInputBufferInner(isTriggeredByOutPort, isFlushed, bufferStatus);
329 }
330 
ProcessInputBufferInner(bool isTriggeredByOutPort,bool isFlushed,uint32_t & bufferStatus)331 void MediaCodec::ProcessInputBufferInner(bool isTriggeredByOutPort, bool isFlushed, uint32_t &bufferStatus)
332 {
333     FALSE_RETURN_MSG_D(inputBufferQueueConsumer_ != nullptr, "inputBufferQueueConsumer is nullptr!");
334     uint32_t filledBufferSize = inputBufferQueueConsumer_->GetFilledBufferSize();
335     uint32_t eosStatus = inputBufferEosStatus_.load();
336     bool isOutAvail = isOutputBufferAvailable_.load();
337     bufferStatus = static_cast<uint32_t>(InOutPortBufferStatus::INIT_IGNORE_RET);
338     MediaAVCodec::AVCodecTrace trace(std::string("MediaCodec::ProcessInputBufferInner:") +
339         (isTriggeredByOutPort ? "1" : "0") + "," + (isFlushed ? "1" : "0") + "," + std::to_string(filledBufferSize) +
340         "," + (isOutAvail ? "1" : "0") + "," + std::to_string(eosStatus));
341     MEDIA_LOG_DD("ProcessInputBufferInnerr isTriggeredByOutPort:" PUBLIC_LOG_D32 ", isFlushed:" PUBLIC_LOG_D32
342         ", isOutAvail:" PUBLIC_LOG_D32 ", filledBufferSize:" PUBLIC_LOG_U32 ", eosStatus:" PUBLIC_LOG_U32,
343         isTriggeredByOutPort, isFlushed, isOutAvail, filledBufferSize, eosStatus);
344     FALSE_RETURN_MSG_D(!isFlushed, "ProcessInputBufferInner isFlushed true");
345     if (filledBufferSize == 0 && isOutputBufferAvailable_.load() && eosStatus == 0) {
346         bufferStatus = static_cast<uint32_t>(InOutPortBufferStatus::OUTPORT_AVAIL);
347         MEDIA_LOG_I("ProcessInputBufferInner ignore");
348         return;
349     }
350 
351     Status ret = Status::OK;
352     // The last process failed to RequestBuffer from outputBufferQueueProducer, perform HandleOutputBufferInner firstly.
353     if (!isOutAvail || eosStatus != 0) {
354         CHECK_AND_RETURN_LOGD(HandleOutputBufferInner(ret, bufferStatus, filledBufferSize, eosStatus),
355             "HandleOutputBufferInner S1, ret:" PUBLIC_LOG_D32, static_cast<int32_t>(ret));
356         inputBufferEosStatus_.store(0);
357     }
358 
359     bool isProcessingNeeded = false;
360     eosStatus = 0;
361     ret = Status::OK;
362     HandleInputBufferInner(eosStatus, isProcessingNeeded, ret);
363     filledBufferSize = inputBufferQueueConsumer_->GetFilledBufferSize();
364     if (!isProcessingNeeded) {
365         if (bufferStatus != static_cast<uint32_t>(InOutPortBufferStatus::INIT_IGNORE_RET)) {
366             filledBufferSize > 0 ? (bufferStatus |= static_cast<uint32_t>(InOutPortBufferStatus::INPORT_AVAIL)) :
367                 (bufferStatus &= ~static_cast<uint32_t>(InOutPortBufferStatus::INPORT_AVAIL));
368         } else {
369             // Normally this case happen with low probability, assuming OutputBuffer available not make negative effect
370             bufferStatus = static_cast<uint32_t>(InOutPortBufferStatus::OUTPORT_AVAIL) |
371                 (filledBufferSize > 0 ? static_cast<uint32_t>(InOutPortBufferStatus::INPORT_AVAIL) : 0);
372         }
373         MEDIA_LOG_I("HandleInputBufferInner failed, ret:" PUBLIC_LOG_D32 ", bufferStatus:" PUBLIC_LOG_U32X,
374             static_cast<int32_t>(ret), bufferStatus);
375         return;
376     }
377 
378     inputBufferEosStatus_.store(eosStatus);
379     CHECK_AND_RETURN_LOGD(HandleOutputBufferInner(ret, bufferStatus, filledBufferSize, eosStatus),
380         "HandleOutputBufferInner S2, ret:" PUBLIC_LOG_D32, static_cast<int32_t>(ret));
381     inputBufferEosStatus_.store(0);
382 }
383 
HandleOutputBufferInner(Status & ret,uint32_t & bufferStatus,uint32_t filledBufferSize,uint32_t eosStatus)384 bool MediaCodec::HandleOutputBufferInner(Status &ret, uint32_t &bufferStatus, uint32_t filledBufferSize,
385     uint32_t eosStatus)
386 {
387     MEDIA_TRACE_DEBUG(std::string("MediaCodec::HandleOutputBufferInner:") + std::to_string(eosStatus));
388     bool isBufferAvailable = false;
389     do {
390         isBufferAvailable = false;
391         ret = HandleOutputBufferOnce(isBufferAvailable, eosStatus, false);
392     } while (ret == Status::ERROR_AGAIN);
393 
394     isOutputBufferAvailable_.store(isBufferAvailable);
395 
396     bool isGoingOn = isBufferAvailable;
397     bufferStatus = (filledBufferSize > 0) ? static_cast<uint32_t>(InOutPortBufferStatus::INPORT_AVAIL) : 0;
398     if (!isBufferAvailable) {
399         bufferStatus |= (eosStatus == MediaAVCodec::AVCODEC_BUFFER_FLAG_EOS) ?
400             static_cast<uint32_t>(InOutPortBufferStatus::OUT_EOS_START) : bufferStatus;
401     } else {
402         bufferStatus |= static_cast<uint32_t>(InOutPortBufferStatus::OUTPORT_AVAIL);
403         if (eosStatus == MediaAVCodec::AVCODEC_BUFFER_FLAG_EOS) {
404             bufferStatus |= static_cast<uint32_t>(InOutPortBufferStatus::OUT_EOS_START) |
405                 static_cast<uint32_t>(InOutPortBufferStatus::OUT_EOS_DONE);
406             inputBufferEosStatus_.store(0);
407             isGoingOn = false;
408             MEDIA_LOG_I("HandleOutputBufferInner OUT_EOS_DONE");
409         }
410     }
411 
412     MEDIA_LOG_DD("HandleOutputBufferInner ret:" PUBLIC_LOG_D32 ", isGoingOn:" PUBLIC_LOG_D32 ", isBufferAvailable:"
413         PUBLIC_LOG_D32 ", eosStatus:" PUBLIC_LOG_U32 ", bufferStatus:" PUBLIC_LOG_U32X,
414         static_cast<int32_t>(ret), isGoingOn, isBufferAvailable, eosStatus, bufferStatus);
415 
416     return isGoingOn;
417 }
418 
ResetBufferStatusInfo()419 void MediaCodec::ResetBufferStatusInfo()
420 {
421     if (cachedOutputBuffer_ && outputBufferQueueProducer_) {
422         outputBufferQueueProducer_->PushBuffer(cachedOutputBuffer_, false);
423         cachedOutputBuffer_ = nullptr;
424     }
425     inputBufferEosStatus_.store(0);
426     isOutputBufferAvailable_.store(true);
427 }
428 
GetInputSurface()429 sptr<Surface> MediaCodec::GetInputSurface()
430 {
431     AutoLock lock(stateMutex_);
432     FALSE_RETURN_V(state_ == CodecState::PREPARED, nullptr);
433     CHECK_AND_RETURN_RET_LOG(!isBufferMode_, nullptr, "GetInputBufferQueue isBufferMode_");
434     isSurfaceMode_ = true;
435     return nullptr;
436 }
437 
Start()438 int32_t MediaCodec::Start()
439 {
440     AutoLock lock(stateMutex_);
441     MEDIA_LOG_I("Start enter");
442     MediaAVCodec::AVCodecTrace trace("MediaCodec::Start");
443     FALSE_RETURN_V(state_ != CodecState::RUNNING, (int32_t)Status::OK);
444     FALSE_RETURN_V(state_ == CodecState::PREPARED || state_ == CodecState::FLUSHED,
445                    (int32_t)Status::ERROR_INVALID_STATE);
446     state_ = CodecState::STARTING;
447     auto ret = codecPlugin_->Start();
448     FALSE_RETURN_V_MSG_E(ret == Status::OK, (int32_t)ret, "plugin start failed");
449     state_ = CodecState::RUNNING;
450     return (int32_t)ret;
451 }
452 
Stop()453 int32_t MediaCodec::Stop()
454 {
455     AutoLock lock(stateMutex_);
456     MediaAVCodec::AVCodecTrace trace("MediaCodec::Stop");
457     MEDIA_LOG_I("Stop enter");
458     FALSE_RETURN_V_MSG_E(codecPlugin_ != nullptr, (int32_t)Status::OK, "codecPlugin_ is nullptr");
459     FALSE_RETURN_V(state_ != CodecState::PREPARED, (int32_t)Status::OK);
460     if (state_ == CodecState::UNINITIALIZED || state_ == CodecState::STOPPING || state_ == CodecState::RELEASING) {
461         MEDIA_LOG_D("Stop, state_=%{public}s", StateToString(state_).data());
462         return (int32_t)Status::OK;
463     }
464     FALSE_RETURN_V(state_ == CodecState::RUNNING || state_ == CodecState::END_OF_STREAM ||
465                    state_ == CodecState::FLUSHED, (int32_t)Status::ERROR_INVALID_STATE);
466     state_ = CodecState::STOPPING;
467     auto ret = codecPlugin_->Stop();
468     MEDIA_LOG_I("codec Stop, state from %{public}s to Stop", StateToString(state_).data());
469     FALSE_RETURN_V_MSG_E(ret == Status::OK, (int32_t)ret, "plugin stop failed");
470     ClearInputBuffer();
471     ResetBufferStatusInfo();
472     state_ = CodecState::PREPARED;
473     return (int32_t)ret;
474 }
475 
Flush()476 int32_t MediaCodec::Flush()
477 {
478     AutoLock lock(stateMutex_);
479     MEDIA_LOG_I("Flush enter");
480     if (state_ == CodecState::FLUSHED) {
481         MEDIA_LOG_W("Flush, state is already flushed, state_=%{public}s .", StateToString(state_).data());
482         return (int32_t)Status::OK;
483     }
484     if (state_ != CodecState::RUNNING && state_ != CodecState::END_OF_STREAM) {
485         MEDIA_LOG_E("Flush failed, state =%{public}s", StateToString(state_).data());
486         return (int32_t)Status::ERROR_INVALID_STATE;
487     }
488     MEDIA_LOG_I("Flush, state from %{public}s to FLUSHING", StateToString(state_).data());
489     state_ = CodecState::FLUSHING;
490     inputBufferQueueProducer_->Clear();
491     auto ret = codecPlugin_->Flush();
492     FALSE_RETURN_V_MSG_E(ret == Status::OK, (int32_t)ret, "plugin flush failed");
493     ClearInputBuffer();
494     ResetBufferStatusInfo();
495     state_ = CodecState::FLUSHED;
496     return (int32_t)ret;
497 }
498 
Reset()499 int32_t MediaCodec::Reset()
500 {
501     AutoLock lock(stateMutex_);
502     MediaAVCodec::AVCodecTrace trace("MediaCodec::Reset");
503     MEDIA_LOG_I("Reset enter");
504     if (state_ == CodecState::UNINITIALIZED || state_ == CodecState::RELEASING) {
505         MEDIA_LOG_W("adapter reset, state is already released, state =%{public}s .", StateToString(state_).data());
506         return (int32_t)Status::OK;
507     }
508     if (state_ == CodecState::INITIALIZING) {
509         MEDIA_LOG_W("adapter reset, state is initialized, state =%{public}s .", StateToString(state_).data());
510         state_ = CodecState::INITIALIZED;
511         return (int32_t)Status::OK;
512     }
513     auto ret = codecPlugin_->Reset();
514     FALSE_RETURN_V_MSG_E(ret == Status::OK, (int32_t)ret, "plugin reset failed");
515     ClearInputBuffer();
516     ResetBufferStatusInfo();
517     state_ = CodecState::INITIALIZED;
518     return (int32_t)ret;
519 }
520 
Release()521 int32_t MediaCodec::Release()
522 {
523     AutoLock lock(stateMutex_);
524     MediaAVCodec::AVCodecTrace trace("MediaCodec::Release");
525     MEDIA_LOG_I("Release enter");
526     FALSE_RETURN_V_MSG_E(codecPlugin_ != nullptr, (int32_t)Status::OK, "codecPlugin_ is nullptr");
527     if (state_ == CodecState::UNINITIALIZED || state_ == CodecState::RELEASING) {
528         MEDIA_LOG_W("codec Release, state isnot completely correct, state =%{public}s .", StateToString(state_).data());
529         return (int32_t)Status::OK;
530     }
531 
532     if (state_ == CodecState::INITIALIZING) {
533         MEDIA_LOG_W("codec Release, state isnot completely correct, state =%{public}s .", StateToString(state_).data());
534         state_ = CodecState::RELEASING;
535         return (int32_t)Status::OK;
536     }
537     MEDIA_LOG_I("codec Release, state from %{public}s to RELEASING", StateToString(state_).data());
538     state_ = CodecState::RELEASING;
539     auto ret = codecPlugin_->Release();
540     FALSE_RETURN_V_MSG_E(ret == Status::OK, (int32_t)ret, "plugin release failed");
541     codecPlugin_ = nullptr;
542     ResetBufferStatusInfo();
543     ClearBufferQueue();
544     if (dumpDataInputFs_ != nullptr && dumpDataInputFs_->is_open()) {
545         dumpDataInputFs_->flush();
546         dumpDataInputFs_->close();
547     }
548     if (dumpDataOutputFs_ != nullptr && dumpDataOutputFs_->is_open()) {
549         dumpDataOutputFs_->flush();
550         dumpDataOutputFs_->close();
551     }
552     state_ = CodecState::UNINITIALIZED;
553     return (int32_t)ret;
554 }
555 
NotifyEos()556 int32_t MediaCodec::NotifyEos()
557 {
558     AutoLock lock(stateMutex_);
559     FALSE_RETURN_V(state_ != CodecState::END_OF_STREAM, (int32_t)Status::OK);
560     FALSE_RETURN_V(state_ == CodecState::RUNNING, (int32_t)Status::ERROR_INVALID_STATE);
561     state_ = CodecState::END_OF_STREAM;
562     return (int32_t)Status::OK;
563 }
564 
SetParameter(const std::shared_ptr<Meta> & parameter)565 int32_t MediaCodec::SetParameter(const std::shared_ptr<Meta> &parameter)
566 {
567     AutoLock lock(stateMutex_);
568     FALSE_RETURN_V(parameter != nullptr, (int32_t)Status::ERROR_INVALID_PARAMETER);
569     FALSE_RETURN_V(state_ != CodecState::UNINITIALIZED && state_ != CodecState::INITIALIZED &&
570                    state_ != CodecState::PREPARED, (int32_t)Status::ERROR_INVALID_STATE);
571     auto ret = codecPlugin_->SetParameter(parameter);
572     FALSE_RETURN_V_MSG_E(ret == Status::OK, (int32_t)ret, "plugin set parameter failed");
573     return (int32_t)ret;
574 }
575 
SetDumpInfo(bool isDump,uint64_t instanceId)576 void MediaCodec::SetDumpInfo(bool isDump, uint64_t instanceId)
577 {
578     (void)instanceId;
579     auto tid = gettid();
580     if (isDump && tid <= 0) {
581         MEDIA_LOG_W("Cannot dump with tid <= 0.");
582         return;
583     }
584     dumpPrefix_ = std::to_string(tid);
585     isDump_ = isDump;
586 }
587 
GetOutputFormat(std::shared_ptr<Meta> & parameter)588 int32_t MediaCodec::GetOutputFormat(std::shared_ptr<Meta> &parameter)
589 {
590     AutoLock lock(stateMutex_);
591     FALSE_RETURN_V_MSG_E(state_ != CodecState::UNINITIALIZED, (int32_t)Status::ERROR_INVALID_STATE,
592                          "status incorrect,get output format failed.");
593     FALSE_RETURN_V(codecPlugin_ != nullptr, (int32_t)Status::ERROR_INVALID_STATE);
594     FALSE_RETURN_V(parameter != nullptr, (int32_t)Status::ERROR_INVALID_PARAMETER);
595     auto ret = codecPlugin_->GetParameter(parameter);
596     FALSE_RETURN_V_MSG_E(ret == Status::OK, (int32_t)ret, "plugin get parameter failed");
597     return (int32_t)ret;
598 }
599 
AttachBufffer()600 Status MediaCodec::AttachBufffer()
601 {
602     MEDIA_LOG_I("AttachBufffer enter");
603     int inputBufferNum = DEFAULT_BUFFER_NUM;
604     MemoryType memoryType;
605 #ifndef MEDIA_OHOS
606     memoryType = MemoryType::VIRTUAL_MEMORY;
607 #else
608     memoryType = MemoryType::SHARED_MEMORY;
609 #endif
610     if (inputBufferQueue_ == nullptr) {
611         inputBufferQueue_ = AVBufferQueue::Create(inputBufferNum, memoryType, INPUT_BUFFER_QUEUE_NAME);
612     }
613     FALSE_RETURN_V_MSG_E(inputBufferQueue_ != nullptr, Status::ERROR_UNKNOWN,
614                          "inputBufferQueue_ is nullptr");
615     inputBufferQueueProducer_ = inputBufferQueue_->GetProducer();
616     std::shared_ptr<Meta> inputBufferConfig = std::make_shared<Meta>();
617     FALSE_RETURN_V_MSG_E(codecPlugin_ != nullptr, Status::ERROR_UNKNOWN, "codecPlugin_ is nullptr");
618     auto ret = codecPlugin_->GetParameter(inputBufferConfig);
619     FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "attachBufffer failed, plugin get param error");
620     int32_t capacity = 0;
621     FALSE_RETURN_V_MSG_E(inputBufferConfig != nullptr, Status::ERROR_UNKNOWN,
622                          "inputBufferConfig is nullptr");
623     FALSE_RETURN_V(inputBufferConfig->Get<Tag::AUDIO_MAX_INPUT_SIZE>(capacity),
624                    Status::ERROR_INVALID_PARAMETER);
625     for (int i = 0; i < inputBufferNum; i++) {
626         std::shared_ptr<AVAllocator> avAllocator;
627 #ifndef MEDIA_OHOS
628         MEDIA_LOG_D("CreateVirtualAllocator,i=%{public}d capacity=%{public}d", i, capacity);
629         avAllocator = AVAllocatorFactory::CreateVirtualAllocator();
630 #else
631         MEDIA_LOG_D("CreateSharedAllocator,i=%{public}d capacity=%{public}d", i, capacity);
632         avAllocator = AVAllocatorFactory::CreateSharedAllocator(MemoryFlag::MEMORY_READ_WRITE);
633 #endif
634         std::shared_ptr<AVBuffer> inputBuffer = AVBuffer::CreateAVBuffer(avAllocator, capacity);
635         FALSE_RETURN_V_MSG_E(inputBuffer != nullptr, Status::ERROR_UNKNOWN,
636                              "inputBuffer is nullptr");
637         FALSE_RETURN_V_MSG_E(inputBufferQueueProducer_ != nullptr, Status::ERROR_UNKNOWN,
638                              "inputBufferQueueProducer_ is nullptr");
639         inputBufferQueueProducer_->AttachBuffer(inputBuffer, false);
640         MEDIA_LOG_I("Attach intput buffer. index: %{public}d, bufferId: %{public}" PRIu64,
641             i, inputBuffer->GetUniqueId());
642         inputBufferVector_.push_back(inputBuffer);
643     }
644     return Status::OK;
645 }
646 
AttachDrmBufffer(std::shared_ptr<AVBuffer> & drmInbuf,std::shared_ptr<AVBuffer> & drmOutbuf,uint32_t size)647 Status MediaCodec::AttachDrmBufffer(std::shared_ptr<AVBuffer> &drmInbuf, std::shared_ptr<AVBuffer> &drmOutbuf,
648     uint32_t size)
649 {
650     MEDIA_LOG_D("AttachDrmBufffer");
651     std::shared_ptr<AVAllocator> avAllocator;
652     avAllocator = AVAllocatorFactory::CreateSharedAllocator(MemoryFlag::MEMORY_READ_WRITE);
653     FALSE_RETURN_V_MSG_E(avAllocator != nullptr, Status::ERROR_UNKNOWN,
654         "avAllocator is nullptr");
655 
656     drmInbuf = AVBuffer::CreateAVBuffer(avAllocator, size);
657     FALSE_RETURN_V_MSG_E(drmInbuf != nullptr, Status::ERROR_UNKNOWN,
658         "drmInbuf is nullptr");
659     FALSE_RETURN_V_MSG_E(drmInbuf->memory_ != nullptr, Status::ERROR_UNKNOWN,
660         "drmInbuf->memory_ is nullptr");
661     drmInbuf->memory_->SetSize(size);
662 
663     drmOutbuf = AVBuffer::CreateAVBuffer(avAllocator, size);
664     FALSE_RETURN_V_MSG_E(drmOutbuf != nullptr, Status::ERROR_UNKNOWN,
665         "drmOutbuf is nullptr");
666     FALSE_RETURN_V_MSG_E(drmOutbuf->memory_ != nullptr, Status::ERROR_UNKNOWN,
667         "drmOutbuf->memory_ is nullptr");
668     drmOutbuf->memory_->SetSize(size);
669     return Status::OK;
670 }
671 
DrmAudioCencDecrypt(std::shared_ptr<AVBuffer> & filledInputBuffer)672 Status MediaCodec::DrmAudioCencDecrypt(std::shared_ptr<AVBuffer> &filledInputBuffer)
673 {
674     MEDIA_LOG_D("DrmAudioCencDecrypt enter");
675     Status ret = Status::OK;
676 
677     // 1. allocate drm buffer
678     uint32_t bufSize = static_cast<uint32_t>(filledInputBuffer->memory_->GetSize());
679     if (bufSize == 0) {
680         MEDIA_LOG_D("MediaCodec DrmAudioCencDecrypt input buffer size equal 0");
681         return ret;
682     }
683     std::shared_ptr<AVBuffer> drmInBuf;
684     std::shared_ptr<AVBuffer> drmOutBuf;
685     ret = AttachDrmBufffer(drmInBuf, drmOutBuf, bufSize);
686     FALSE_RETURN_V_MSG_E(ret == Status::OK, Status::ERROR_UNKNOWN, "AttachDrmBufffer failed");
687 
688     // 2. copy data to drm input buffer
689     int32_t drmRes = memcpy_s(drmInBuf->memory_->GetAddr(), bufSize,
690         filledInputBuffer->memory_->GetAddr(), bufSize);
691     FALSE_RETURN_V_MSG_E(drmRes == 0, Status::ERROR_UNKNOWN, "memcpy_s drmInBuf failed");
692     if (filledInputBuffer->meta_ != nullptr) {
693         *(drmInBuf->meta_) = *(filledInputBuffer->meta_);
694     }
695     // 4. decrypt
696     drmRes = drmDecryptor_->DrmAudioCencDecrypt(drmInBuf, drmOutBuf, bufSize);
697     FALSE_RETURN_V_MSG_E(drmRes == 0, Status::ERROR_DRM_DECRYPT_FAILED, "DrmAudioCencDecrypt return error");
698 
699     // 5. copy decrypted data from drm output buffer back
700     drmRes = memcpy_s(filledInputBuffer->memory_->GetAddr(), bufSize,
701         drmOutBuf->memory_->GetAddr(), bufSize);
702     FALSE_RETURN_V_MSG_E(drmRes == 0, Status::ERROR_UNKNOWN, "memcpy_s drmOutBuf failed");
703     return Status::OK;
704 }
705 
HandleAudioCencDecryptError()706 void MediaCodec::HandleAudioCencDecryptError()
707 {
708     MEDIA_LOG_E("MediaCodec DrmAudioCencDecrypt failed.");
709     auto realPtr = mediaCodecCallback_.lock();
710     if (realPtr != nullptr) {
711         realPtr->OnError(CodecErrorType::CODEC_DRM_DECRYTION_FAILED,
712             static_cast<int32_t>(Status::ERROR_DRM_DECRYPT_FAILED));
713     }
714 }
715 
PrepareInputBufferQueue()716 int32_t MediaCodec::PrepareInputBufferQueue()
717 {
718     MEDIA_LOG_I("PrepareInputBufferQueue enter");
719     std::vector<std::shared_ptr<AVBuffer>> inputBuffers;
720     MediaAVCodec::AVCodecTrace trace("MediaCodec::PrepareInputBufferQueue");
721     FALSE_RETURN_V_MSG_E(codecPlugin_ != nullptr, (int32_t)Status::ERROR_UNKNOWN, "codecPlugin_ is nullptr");
722     auto ret = codecPlugin_->GetInputBuffers(inputBuffers);
723     FALSE_RETURN_V_MSG_E(ret == Status::OK, (int32_t)ret, "pluign getInputBuffers failed");
724     if (inputBuffers.empty()) {
725         ret = AttachBufffer();
726         if (ret != Status::OK) {
727             MEDIA_LOG_E("GetParameter failed");
728             return (int32_t)ret;
729         }
730     } else {
731         if (inputBufferQueue_ == nullptr) {
732             inputBufferQueue_ =
733                 AVBufferQueue::Create(inputBuffers.size(), MemoryType::HARDWARE_MEMORY, INPUT_BUFFER_QUEUE_NAME);
734         }
735         FALSE_RETURN_V_MSG_E(inputBufferQueue_ != nullptr, (int32_t)Status::ERROR_UNKNOWN,
736                              "inputBufferQueue_ is nullptr");
737         inputBufferQueueProducer_ = inputBufferQueue_->GetProducer();
738         for (uint32_t i = 0; i < inputBuffers.size(); i++) {
739             inputBufferQueueProducer_->AttachBuffer(inputBuffers[i], false);
740             inputBufferVector_.push_back(inputBuffers[i]);
741         }
742     }
743     FALSE_RETURN_V_MSG_E(inputBufferQueue_ != nullptr, (int32_t)Status::ERROR_UNKNOWN, "inputBufferQueue_ is nullptr");
744     inputBufferQueueConsumer_ = inputBufferQueue_->GetConsumer();
745     sptr<IConsumerListener> listener = new InputBufferAvailableListener(shared_from_this());
746     FALSE_RETURN_V_MSG_E(inputBufferQueueConsumer_ != nullptr, (int32_t)Status::ERROR_UNKNOWN,
747                          "inputBufferQueueConsumer_ is nullptr");
748     inputBufferQueueConsumer_->SetBufferAvailableListener(listener);
749     return (int32_t)ret;
750 }
751 
PrepareOutputBufferQueue()752 int32_t MediaCodec::PrepareOutputBufferQueue()
753 {
754     MEDIA_LOG_I("PrepareOutputBufferQueue enter");
755     std::vector<std::shared_ptr<AVBuffer>> outputBuffers;
756     MediaAVCodec::AVCodecTrace trace("MediaCodec::PrepareOutputBufferQueue");
757     FALSE_RETURN_V_MSG_E(codecPlugin_ != nullptr, (int32_t)Status::ERROR_INVALID_STATE, "codecPlugin_ is nullptr");
758     auto ret = codecPlugin_->GetOutputBuffers(outputBuffers);
759     FALSE_RETURN_V_MSG_E(ret == Status::OK, (int32_t)ret, "GetOutputBuffers failed");
760     FALSE_RETURN_V_MSG_E(outputBufferQueueProducer_ != nullptr, (int32_t)Status::ERROR_INVALID_STATE,
761                          "outputBufferQueueProducer_ is nullptr");
762     if (outputBuffers.empty()) {
763         int outputBufferNum = 30;
764         std::shared_ptr<Meta> outputBufferConfig = std::make_shared<Meta>();
765         ret = codecPlugin_->GetParameter(outputBufferConfig);
766         FALSE_RETURN_V_MSG_E(ret == Status::OK, (int32_t)ret, "GetParameter failed");
767         FALSE_RETURN_V_MSG_E(outputBufferConfig != nullptr, (int32_t)Status::ERROR_INVALID_STATE,
768                              "outputBufferConfig is nullptr");
769         FALSE_RETURN_V(outputBufferConfig->Get<Tag::AUDIO_MAX_OUTPUT_SIZE>(outputBufferCapacity_),
770                        (int32_t)Status::ERROR_INVALID_PARAMETER);
771         for (int i = 0; i < outputBufferNum; i++) {
772             auto avAllocator = AVAllocatorFactory::CreateSharedAllocator(MemoryFlag::MEMORY_READ_WRITE);
773             std::shared_ptr<AVBuffer> outputBuffer = AVBuffer::CreateAVBuffer(avAllocator, outputBufferCapacity_);
774             FALSE_RETURN_V_MSG_E(outputBuffer != nullptr, (int32_t)Status::ERROR_INVALID_STATE,
775                                  "outputBuffer is nullptr");
776             if (outputBufferQueueProducer_->AttachBuffer(outputBuffer, false) == Status::OK) {
777                 MEDIA_LOG_D("Attach output buffer. index: %{public}d, bufferId: %{public}" PRIu64, i,
778                             outputBuffer->GetUniqueId());
779                 outputBufferVector_.push_back(outputBuffer);
780             }
781         }
782     } else {
783         for (uint32_t i = 0; i < outputBuffers.size(); i++) {
784             if (outputBufferQueueProducer_->AttachBuffer(outputBuffers[i], false) == Status::OK) {
785                 MEDIA_LOG_D("Attach output buffer. index: %{public}d, bufferId: %{public}" PRIu64, i,
786                             outputBuffers[i]->GetUniqueId());
787                 outputBufferVector_.push_back(outputBuffers[i]);
788             }
789         }
790     }
791     FALSE_RETURN_V_MSG_E(outputBufferVector_.size() > 0, (int32_t)Status::ERROR_INVALID_STATE, "Attach no buffer");
792     return (int32_t)ret;
793 }
794 
ProcessInputBuffer()795 void MediaCodec::ProcessInputBuffer()
796 {
797     MEDIA_LOG_DD("ProcessInputBuffer enter");
798     MEDIA_TRACE_DEBUG("MediaCodec::ProcessInputBuffer");
799 
800     bool isProcessingNeeded = false;
801     Status ret = Status::OK;
802     uint32_t eosStatus = 0;
803     HandleInputBufferInner(eosStatus, isProcessingNeeded, ret);
804     CHECK_AND_RETURN_LOG(isProcessingNeeded, "ProcessInputBuffer failed %{public}d", static_cast<int32_t>(ret));
805 
806     do {
807         ret = HandleOutputBuffer(eosStatus);
808     } while (ret == Status::ERROR_AGAIN);
809 }
810 
HandleInputBufferInner(uint32_t & eosStatus,bool & isProcessingNeeded,Status & ret)811 void MediaCodec::HandleInputBufferInner(uint32_t &eosStatus, bool &isProcessingNeeded, Status &ret)
812 {
813     MEDIA_TRACE_DEBUG_POSTFIX("MediaCodec::HandleInputBufferInner", "1");
814 
815     std::shared_ptr<AVBuffer> filledInputBuffer;
816     if (state_ != CodecState::RUNNING) {
817         MEDIA_LOG_I("HandleInputBufferInner status changed, current status is not running");
818         ret = Status::ERROR_INVALID_STATE;
819         return;
820     }
821     {
822         MEDIA_TRACE_DEBUG_POSTFIX("MediaCodec::HandleInputBufferInner-AcquireBuffer", "2");
823         ret = inputBufferQueueConsumer_->AcquireBuffer(filledInputBuffer);
824         CHECK_AND_RETURN_LOG(ret == Status::OK && filledInputBuffer, "HandleInputBufferInner AcquireBuffer fail");
825     }
826     if (state_ != CodecState::RUNNING) {
827         MEDIA_LOG_W("HandleInputBufferInner not running, ReleaseBuffer name:MediaCodecInputBufferQueue");
828         inputBufferQueueConsumer_->ReleaseBuffer(filledInputBuffer);
829         ret = Status::ERROR_INVALID_STATE;
830         return;
831     }
832     uint32_t flag = filledInputBuffer->flag_;
833     int8_t retryCount = 0;
834     do {
835         if (drmDecryptor_ != nullptr) {
836             MediaAVCodec::AVCodecTrace trace("MediaCodec::HandleInputBufferInner-DrmAudioCencDecrypt");
837             ret = DrmAudioCencDecrypt(filledInputBuffer);
838             if (ret != Status::OK) {
839                 HandleAudioCencDecryptError();
840                 break;
841             }
842         }
843 
844         ret = CodePluginInputBuffer(filledInputBuffer);
845         if (ret != Status::OK) {
846             retryCount++;
847             continue;
848         }
849     } while (ret != Status::OK && retryCount < RETRY && state_ == CodecState::RUNNING);
850 
851     if (ret != Status::OK || state_ != CodecState::RUNNING) {
852         inputBufferQueueConsumer_->ReleaseBuffer(filledInputBuffer);
853         MEDIA_LOG_E("Plugin queueInputBuffer failed, state_:%{public}d, ret:%{public}d", state_.load(), ret);
854         return;
855     }
856     isProcessingNeeded = true;
857     eosStatus = flag;
858 }
859 
860 #ifdef SUPPORT_DRM
SetAudioDecryptionConfig(const sptr<DrmStandard::IMediaKeySessionService> & keySession,const bool svpFlag)861 int32_t MediaCodec::SetAudioDecryptionConfig(const sptr<DrmStandard::IMediaKeySessionService> &keySession,
862     const bool svpFlag)
863 {
864     MEDIA_LOG_I("MediaCodec::SetAudioDecryptionConfig");
865     if (drmDecryptor_ == nullptr) {
866         drmDecryptor_ = std::make_shared<MediaAVCodec::CodecDrmDecrypt>();
867     }
868     FALSE_RETURN_V_MSG_E(drmDecryptor_ != nullptr, (int32_t)Status::ERROR_NO_MEMORY, "drmDecryptor is nullptr");
869     drmDecryptor_->SetDecryptionConfig(keySession, svpFlag);
870     return (int32_t)Status::OK;
871 }
872 #else
SetAudioDecryptionConfig(const sptr<DrmStandard::IMediaKeySessionService> & keySession,const bool svpFlag)873 int32_t MediaCodec::SetAudioDecryptionConfig(const sptr<DrmStandard::IMediaKeySessionService> &keySession,
874     const bool svpFlag)
875 {
876     MEDIA_LOG_I("MediaCodec::SetAudioDecryptionConfig, Not support");
877     (void)keySession;
878     (void)svpFlag;
879     return (int32_t)Status::OK;
880 }
881 #endif
882 
ChangePlugin(const std::string & mime,bool isEncoder,const std::shared_ptr<Meta> & meta)883 Status MediaCodec::ChangePlugin(const std::string &mime, bool isEncoder, const std::shared_ptr<Meta> &meta)
884 {
885     Status ret = Status::OK;
886     Plugins::PluginType type;
887     if (isEncoder) {
888         type = Plugins::PluginType::AUDIO_ENCODER;
889     } else {
890         type = Plugins::PluginType::AUDIO_DECODER;
891     }
892 
893     {
894         AutoLock pluginLock(codecPluginMutex_);
895         if (codecPlugin_ != nullptr) {
896             codecPlugin_->Release();
897             codecPlugin_ = nullptr;
898         }
899         codecPlugin_ = CreatePlugin(mime, type);
900 
901         CHECK_AND_RETURN_RET_LOG(codecPlugin_ != nullptr, Status::ERROR_INVALID_PARAMETER, "createPlugin failed");
902         ret = codecPlugin_->SetParameter(meta);
903         if (ret != Status::OK) {
904             MEDIA_LOG_E("codecPlugin SetParameter ret %{public}d", ret);
905             return ret;
906         }
907         ret = codecPlugin_->Init();
908         if (ret != Status::OK) {
909             MEDIA_LOG_E("codecPlugin Init ret %{public}d", ret);
910             return ret;
911         }
912         ret = codecPlugin_->SetDataCallback(this);
913         if (ret != Status::OK) {
914             MEDIA_LOG_E("codecPlugin SetDataCallback ret %{public}d", ret);
915             return ret;
916         }
917     }
918 
919     // discard undecoded data and unconsumed decoded data.
920     inputBufferQueueProducer_->Clear();
921     FALSE_RETURN_V_MSG_E(inputBufferQueue_ != nullptr, Status::ERROR_UNKNOWN, "inputBufferQueue_ is nullptr");
922     ClearInputBuffer();
923     ResetBufferStatusInfo();
924 
925     AutoLock lock(stateMutex_);
926     PrepareInputBufferQueue();
927     PrepareOutputBufferQueue();
928     if (state_ == CodecState::RUNNING) {
929         ret = codecPlugin_->Start();
930         if (ret != Status::OK) {
931             MEDIA_LOG_E("codecPlugin Start ret %{public}d", ret);
932         }
933     }
934 
935     return ret;
936 }
937 
HandleOutputBuffer(uint32_t eosStatus)938 Status MediaCodec::HandleOutputBuffer(uint32_t eosStatus)
939 {
940     MEDIA_LOG_DD("HandleOutputBuffer enter");
941     bool isBufferAvailable = false;
942     Status ret = HandleOutputBufferOnce(isBufferAvailable, eosStatus, true);
943     MEDIA_LOG_DD("HandleOutputBuffer ret:%{public}d, isBufferAvailable:%{public}d", ret, isBufferAvailable);
944     return ret;
945 }
946 
HandleOutputBufferOnce(bool & isBufferAvailable,uint32_t eosStatus,bool isSync)947 Status MediaCodec::HandleOutputBufferOnce(bool &isBufferAvailable, uint32_t eosStatus, bool isSync)
948 {
949     MEDIA_TRACE_DEBUG_POSTFIX("MediaCodec::HandleOutputBufferOnce-isSync:" + std::to_string(isSync), "1");
950     Status ret = Status::OK;
951     std::shared_ptr<AVBuffer> emptyOutputBuffer;
952     AVBufferConfig avBufferConfig;
953     if (cachedOutputBuffer_) {
954         std::swap(emptyOutputBuffer, cachedOutputBuffer_);
955     } else {
956         if (isSync) {
957             MediaAVCodec::AVCodecTrace traceRequestBuffer("MediaCodec::HandleOutputBufferOnce-RequestBuffer-sync");
958             do {
959                 ret = outputBufferQueueProducer_->RequestBuffer(emptyOutputBuffer, avBufferConfig, TIME_OUT_MS);
960             } while (ret != Status::OK && state_ == CodecState::RUNNING);
961         } else {
962             MEDIA_TRACE_DEBUG_POSTFIX("MediaCodec::HandleOutputBufferOnce-RequestBuffer-async", "2");
963             ret = outputBufferQueueProducer_->RequestBuffer(emptyOutputBuffer, avBufferConfig, TIME_OUT_MS_INNER);
964         }
965     }
966 
967     if (emptyOutputBuffer) {
968         emptyOutputBuffer->flag_ = eosStatus;
969         isBufferAvailable = true;
970     } else if (state_ != CodecState::RUNNING) {
971         return Status::OK;
972     } else {
973         return Status::ERROR_NULL_POINTER;
974     }
975 
976     ret = CodePluginOutputBuffer(emptyOutputBuffer);
977     if (ret == Status::ERROR_NOT_ENOUGH_DATA) {
978         MEDIA_LOG_DD("HandleOutputBufferOnce QueueOutputBuffer ERROR_NOT_ENOUGH_DATA");
979         // To cache the empty OutputBuffer returned by RequestBuffer to improve performance
980         std::swap(emptyOutputBuffer, cachedOutputBuffer_);
981     } else if (ret == Status::ERROR_AGAIN) {
982         MEDIA_LOG_DD("HandleOutputBufferOnce The output data is not completely read, needs to be read again");
983     } else if (ret == Status::END_OF_STREAM) {
984         MEDIA_LOG_I("HandleOutputBufferOnce QueueOutputBuffer END_OF_STREAM");
985     } else if (ret != Status::OK) {
986         MEDIA_LOG_E("HandleOutputBufferOnce QueueOutputBuffer error");
987         outputBufferQueueProducer_->PushBuffer(emptyOutputBuffer, false);
988     }
989     return ret;
990 }
991 
OnInputBufferDone(const std::shared_ptr<AVBuffer> & inputBuffer)992 void MediaCodec::OnInputBufferDone(const std::shared_ptr<AVBuffer> &inputBuffer)
993 {
994     FALSE_RETURN_MSG(inputBuffer != nullptr, "OnInputBufferDone fail, inputBuffer nullptr");
995     MediaAVCodec::AVCodecTrace trace(("MediaCodec::OnInputBufferDone:") +
996         std::to_string(inputBuffer->flag_) + "," + std::to_string(inputBuffer->pts_) +
997         "," + std::to_string(inputBuffer->duration_));
998     if (dumpIOEnable == "true" && dumpDataInputFs_) {
999         if (dumpDataInputFs_->is_open() && inputBuffer->memory_->GetAddr()) {
1000             MEDIA_LOG_DD("dumpIOE writing");
1001             dumpDataInputFs_->write(reinterpret_cast<const char*>(inputBuffer->memory_->GetAddr() +
1002                                     inputBuffer->memory_->GetOffset()), inputBuffer->memory_->GetSize());
1003         }
1004     }
1005     Status ret = inputBufferQueueConsumer_->ReleaseBuffer(inputBuffer);
1006     MEDIA_LOG_DD("0x%{public}06" PRIXPTR " OnInputBufferDone, buffer->pts:" PUBLIC_LOG_D64,
1007         FAKE_POINTER(this), inputBuffer->pts_);
1008     FALSE_RETURN_MSG(ret == Status::OK, "OnInputBufferDone fail");
1009 }
1010 
OnOutputBufferDone(const std::shared_ptr<AVBuffer> & outputBuffer)1011 void MediaCodec::OnOutputBufferDone(const std::shared_ptr<AVBuffer> &outputBuffer)
1012 {
1013     FALSE_RETURN_MSG(outputBuffer != nullptr, "OnOutputBufferDone fail, outputBuffer nullptr");
1014     MediaAVCodec::AVCodecTrace trace(("MediaCodec::OnOutputBufferDone:") +
1015         std::to_string(outputBuffer->flag_) + "," + std::to_string(outputBuffer->pts_) +
1016         "," + std::to_string(outputBuffer->duration_));
1017     if (isDump_) {
1018         DumpAVBufferToFile(DUMP_PARAM, dumpPrefix_ + DUMP_FILE_NAME, outputBuffer);
1019     }
1020     if (dumpIOEnable == "true" && dumpDataOutputFs_) {
1021         if (dumpDataOutputFs_->is_open() && outputBuffer->memory_->GetAddr()) {
1022             MEDIA_LOG_DD("dumpIOE writing");
1023             dumpDataOutputFs_->write(reinterpret_cast<const char*>(outputBuffer->memory_->GetAddr() +
1024                                      outputBuffer->memory_->GetOffset()), outputBuffer->memory_->GetSize());
1025         }
1026     }
1027     Status ret = outputBufferQueueProducer_->PushBuffer(outputBuffer, true);
1028     auto realPtr = mediaCodecCallback_.lock();
1029     if (realPtr != nullptr) {
1030         realPtr->OnOutputBufferDone(outputBuffer);
1031     }
1032     MEDIA_LOG_DD("0x%{public}06" PRIXPTR " OnOutputBufferDone, buffer->pts:" PUBLIC_LOG_D64,
1033         FAKE_POINTER(this), outputBuffer->pts_);
1034     FALSE_RETURN_MSG(ret == Status::OK, "OnOutputBufferDone fail");
1035 }
1036 
ClearBufferQueue()1037 void MediaCodec::ClearBufferQueue()
1038 {
1039     MEDIA_LOG_I("ClearBufferQueue called.");
1040     if (inputBufferQueueProducer_ != nullptr) {
1041         for (const auto &buffer : inputBufferVector_) {
1042             inputBufferQueueProducer_->DetachBuffer(buffer);
1043         }
1044         inputBufferVector_.clear();
1045         inputBufferQueueProducer_->SetQueueSize(0);
1046     }
1047     if (outputBufferQueueProducer_ != nullptr) {
1048         for (const auto &buffer : outputBufferVector_) {
1049             outputBufferQueueProducer_->DetachBuffer(buffer);
1050         }
1051         outputBufferVector_.clear();
1052         outputBufferQueueProducer_->SetQueueSize(0);
1053     }
1054 }
1055 
ClearInputBuffer()1056 void MediaCodec::ClearInputBuffer()
1057 {
1058     MediaAVCodec::AVCodecTrace trace("MediaCodec::ClearInputBuffer");
1059     MEDIA_LOG_D("ClearInputBuffer enter");
1060     if (!inputBufferQueueConsumer_) {
1061         return;
1062     }
1063     std::shared_ptr<AVBuffer> filledInputBuffer;
1064     Status ret = Status::OK;
1065     while (ret == Status::OK) {
1066         ret = inputBufferQueueConsumer_->AcquireBuffer(filledInputBuffer);
1067         if (ret != Status::OK) {
1068             MEDIA_LOG_I("clear input Buffer");
1069             return;
1070         }
1071         inputBufferQueueConsumer_->ReleaseBuffer(filledInputBuffer);
1072     }
1073 }
1074 
OnEvent(const std::shared_ptr<Plugins::PluginEvent> event)1075 void MediaCodec::OnEvent(const std::shared_ptr<Plugins::PluginEvent> event)
1076 {
1077     if (event->type != Plugins::PluginEventType::AUDIO_OUTPUT_FORMAT_CHANGED) {
1078         return;
1079     }
1080 
1081     if (!isSupportAudioFormatChanged_) {
1082         MEDIA_LOG_W("receive audio format changed but api version is low");
1083         return;
1084     }
1085 
1086     auto realPtr = mediaCodecCallback_.lock();
1087     if (realPtr != nullptr) {
1088         std::shared_ptr<Meta> format = std::make_shared<Meta>(AnyCast<Meta>(event->param));
1089         realPtr->OnOutputFormatChanged(format);
1090     } else {
1091         MEDIA_LOG_E("receive AUDIO_OUTPUT_FORMAT_CHANGED, but lock callback fail");
1092     }
1093 }
1094 
StateToString(CodecState state)1095 std::string MediaCodec::StateToString(CodecState state)
1096 {
1097     std::map<CodecState, std::string> stateStrMap = {
1098         {CodecState::UNINITIALIZED, " UNINITIALIZED"},
1099         {CodecState::INITIALIZED, " INITIALIZED"},
1100         {CodecState::FLUSHED, " FLUSHED"},
1101         {CodecState::RUNNING, " RUNNING"},
1102         {CodecState::INITIALIZING, " INITIALIZING"},
1103         {CodecState::STARTING, " STARTING"},
1104         {CodecState::STOPPING, " STOPPING"},
1105         {CodecState::FLUSHING, " FLUSHING"},
1106         {CodecState::RESUMING, " RESUMING"},
1107         {CodecState::RELEASING, " RELEASING"},
1108     };
1109     return stateStrMap[state];
1110 }
1111 
OnDumpInfo(int32_t fd)1112 void MediaCodec::OnDumpInfo(int32_t fd)
1113 {
1114     MEDIA_LOG_D("MediaCodec::OnDumpInfo called.");
1115     if (fd < 0) {
1116         MEDIA_LOG_E("MediaCodec::OnDumpInfo fd is invalid.");
1117         return;
1118     }
1119     std::string dumpString;
1120     dumpString += "MediaCodec plugin name: " + codecPluginName_ + "\n";
1121     dumpString += "MediaCodec buffer size is:" + std::to_string(inputBufferQueue_->GetQueueSize()) + "\n";
1122     int ret = write(fd, dumpString.c_str(), dumpString.size());
1123     if (ret < 0) {
1124         MEDIA_LOG_E("MediaCodec::OnDumpInfo write failed.");
1125         return;
1126     }
1127 }
1128 
GetApiVersion()1129 uint32_t MediaCodec::GetApiVersion()
1130 {
1131     uint32_t apiVersion = INVALID_API_VERSION;
1132     OHOS::sptr<OHOS::ISystemAbilityManager> systemAbilityManager =
1133         OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
1134     OHOS::sptr<OHOS::IRemoteObject> remoteObject =
1135         systemAbilityManager->CheckSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
1136     sptr<AppExecFwk::IBundleMgr> iBundleMgr = OHOS::iface_cast<AppExecFwk::IBundleMgr>(remoteObject);
1137     if (iBundleMgr == nullptr) {
1138         MEDIA_LOG_W("GetApiVersion IBundleMgr is nullptr");
1139         return apiVersion;
1140     }
1141     AppExecFwk::BundleInfo bundleInfo;
1142     if (iBundleMgr->GetBundleInfoForSelf(0, bundleInfo) == ERR_OK) {
1143         apiVersion = bundleInfo.targetVersion % API_VERSION_MOD;
1144         MEDIA_LOG_I("GetApiVersion targetVersion: %{public}u", bundleInfo.targetVersion);
1145     } else {
1146         MEDIA_LOG_W("GetApiVersion failed, call by SA or test maybe");
1147     }
1148     return apiVersion;
1149 }
1150 
CodePluginInputBuffer(const std::shared_ptr<AVBuffer> & inputBuffer)1151 Status MediaCodec::CodePluginInputBuffer(const std::shared_ptr<AVBuffer> &inputBuffer)
1152 {
1153     AutoLock pluginLock(codecPluginMutex_);
1154     if (codecPlugin_ != nullptr) {
1155         MEDIA_TRACE_DEBUG(std::string("MediaCodec::CodePluginInputBuffer-QueueInputBuffer:") +
1156             std::to_string(inputBuffer->flag_) + "," + std::to_string(inputBuffer->pts_) +
1157             "," + std::to_string(inputBuffer->duration_));
1158         return codecPlugin_->QueueInputBuffer(inputBuffer);
1159     } else {
1160         MEDIA_LOG_E("plugin is null");
1161         return Status::ERROR_UNKNOWN;
1162     }
1163 }
1164 
CodePluginOutputBuffer(std::shared_ptr<AVBuffer> & outputBuffer)1165 Status MediaCodec::CodePluginOutputBuffer(std::shared_ptr<AVBuffer> &outputBuffer)
1166 {
1167     AutoLock pluginLock(codecPluginMutex_);
1168     FALSE_RETURN_V_MSG_E(codecPlugin_ != nullptr, Status::ERROR_INVALID_STATE, "plugin is null");
1169 
1170     MEDIA_TRACE_DEBUG("MediaCodec::CodePluginOutputBuffer");
1171     return codecPlugin_->QueueOutputBuffer(outputBuffer);
1172 }
1173 
1174 } // namespace Media
1175 } // namespace OHOS
1176