• 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 
16 #include "codec_server.h"
17 #include <functional>
18 #include <limits>
19 #include <malloc.h>
20 #include <map>
21 #include <unistd.h>
22 #include <vector>
23 #include "avcodec_codec_name.h"
24 #include "avcodec_dump_utils.h"
25 #include "avcodec_errors.h"
26 #include "avcodec_log.h"
27 #include "avcodec_sysevent.h"
28 #include "buffer/avbuffer.h"
29 #include "codec_ability_singleton.h"
30 #include "codec_factory.h"
31 #include "media_description.h"
32 #include "meta/meta_key.h"
33 #include "surface_type.h"
34 #ifdef SUPPORT_DRM
35 #include "i_keysession_service.h"
36 #endif
37 #ifdef AVCODEC_SUPPORT_EVENT_MANAGER
38 #include "event_manager.h"
39 #endif
40 
41 namespace {
42 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_FRAMEWORK, "CodecServer"};
43 enum DumpIndex : uint32_t {
44     DUMP_INDEX_FORWARD_CALLER_PID          = 0x01'01'01'00,
45     DUMP_INDEX_FORWARD_CALLER_UID          = 0x01'01'02'00,
46     DUMP_INDEX_FORWARD_CALLER_PROCESS_NAME = 0x01'01'03'00,
47     DUMP_INDEX_CALLER_PID                  = 0x01'01'04'00,
48     DUMP_INDEX_CALLER_UID                  = 0x01'01'05'00,
49     DUMP_INDEX_CALLER_PROCESS_NAME         = 0x01'01'06'00,
50     DUMP_INDEX_INSTANCE_ID                 = 0x01'01'07'00,
51     DUMP_INDEX_STATUS                      = 0x01'01'08'00,
52     DUMP_INDEX_LAST_ERROR                  = 0x01'01'09'00,
53     DUMP_INDEX_CODEC_INFO_START            = 0x01'02'00'00,
54 };
55 constexpr uint32_t DUMP_OFFSET_8 = 8;
56 
57 const std::map<OHOS::MediaAVCodec::CodecServer::CodecStatus, std::string> CODEC_STATE_MAP = {
58     {OHOS::MediaAVCodec::CodecServer::UNINITIALIZED, "uninitialized"},
59     {OHOS::MediaAVCodec::CodecServer::INITIALIZED, "initialized"},
60     {OHOS::MediaAVCodec::CodecServer::CONFIGURED, "configured"},
61     {OHOS::MediaAVCodec::CodecServer::RUNNING, "running"},
62     {OHOS::MediaAVCodec::CodecServer::FLUSHED, "flushed"},
63     {OHOS::MediaAVCodec::CodecServer::END_OF_STREAM, "EOS"},
64     {OHOS::MediaAVCodec::CodecServer::ERROR, "error"},
65 };
66 
67 const std::vector<std::pair<std::string_view, const std::string>> VIDEO_DUMP_TABLE = {
68     {OHOS::MediaAVCodec::MediaDescriptionKey::MD_KEY_CODEC_NAME, "CodecName"},
69     {OHOS::MediaAVCodec::MediaDescriptionKey::MD_KEY_WIDTH, "Width"},
70     {OHOS::MediaAVCodec::MediaDescriptionKey::MD_KEY_HEIGHT, "Height"},
71     {OHOS::MediaAVCodec::MediaDescriptionKey::MD_KEY_FRAME_RATE, "FrameRate"},
72     {OHOS::MediaAVCodec::MediaDescriptionKey::MD_KEY_BITRATE, "BitRate"},
73     {OHOS::MediaAVCodec::MediaDescriptionKey::MD_KEY_PIXEL_FORMAT, "PixelFormat"},
74     {OHOS::MediaAVCodec::MediaDescriptionKey::MD_KEY_SCALE_TYPE, "ScaleType"},
75     {OHOS::MediaAVCodec::MediaDescriptionKey::MD_KEY_ROTATION_ANGLE, "RotationAngle"},
76     {OHOS::MediaAVCodec::MediaDescriptionKey::MD_KEY_MAX_INPUT_SIZE, "MaxInputSize"},
77     {OHOS::MediaAVCodec::MediaDescriptionKey::MD_KEY_MAX_INPUT_BUFFER_COUNT, "MaxInputBufferCount"},
78     {OHOS::MediaAVCodec::MediaDescriptionKey::MD_KEY_MAX_OUTPUT_BUFFER_COUNT, "MaxOutputBufferCount"},
79 };
80 
81 const std::map<int32_t, const std::string> PIXEL_FORMAT_STRING_MAP = {
82     {static_cast<int32_t>(OHOS::MediaAVCodec::VideoPixelFormat::YUV420P), "YUV420P"},
83     {static_cast<int32_t>(OHOS::MediaAVCodec::VideoPixelFormat::YUVI420), "YUVI420"},
84     {static_cast<int32_t>(OHOS::MediaAVCodec::VideoPixelFormat::NV12), "NV12"},
85     {static_cast<int32_t>(OHOS::MediaAVCodec::VideoPixelFormat::NV21), "NV21"},
86     {static_cast<int32_t>(OHOS::MediaAVCodec::VideoPixelFormat::SURFACE_FORMAT), "SURFACE_FORMAT"},
87     {static_cast<int32_t>(OHOS::MediaAVCodec::VideoPixelFormat::RGBA), "RGBA"},
88     {static_cast<int32_t>(OHOS::MediaAVCodec::VideoPixelFormat::UNKNOWN), "UNKNOWN_FORMAT"},
89 };
90 
91 const std::map<int32_t, const std::string> SCALE_TYPE_STRING_MAP = {
92     {OHOS::ScalingMode::SCALING_MODE_FREEZE, "Freeze"},
93     {OHOS::ScalingMode::SCALING_MODE_SCALE_TO_WINDOW, "Scale to window"},
94     {OHOS::ScalingMode::SCALING_MODE_SCALE_CROP, "Scale crop"},
95     {OHOS::ScalingMode::SCALING_MODE_NO_SCALE_CROP, "No scale crop"},
96 };
97 
GetAudioCodecName(const OHOS::MediaAVCodec::AVCodecType type,std::string & name)98 int32_t GetAudioCodecName(const OHOS::MediaAVCodec::AVCodecType type, std::string &name)
99 {
100     using namespace OHOS::MediaAVCodec;
101     if (name.compare(AVCodecCodecName::AUDIO_DECODER_API9_AAC_NAME) == 0) {
102         name = AVCodecCodecName::AUDIO_DECODER_AAC_NAME;
103     } else if (name.compare(AVCodecCodecName::AUDIO_ENCODER_API9_AAC_NAME) == 0) {
104         name = AVCodecCodecName::AUDIO_ENCODER_AAC_NAME;
105     }
106     if (name.find("Audio") != name.npos) {
107         if ((name.find("Decoder") != name.npos && type != AVCODEC_TYPE_AUDIO_DECODER) ||
108             (name.find("Encoder") != name.npos && type != AVCODEC_TYPE_AUDIO_ENCODER)) {
109             AVCODEC_LOGE("AudioCodec name:%{public}s invalid", name.c_str());
110             return AVCS_ERR_INVALID_OPERATION;
111         }
112     }
113     return AVCS_ERR_OK;
114 }
115 
116 struct PostProcessingCallbackUserData {
117     std::shared_ptr<OHOS::MediaAVCodec::CodecServer> codecServer;
118 };
119 
PostProcessingCallbackOnError(int32_t errorCode,void * userData)120 void PostProcessingCallbackOnError(int32_t errorCode, void* userData)
121 {
122     CHECK_AND_RETURN_LOG(userData != nullptr, "Post processing callback's userData is nullptr");
123     auto callbackUserData = static_cast<PostProcessingCallbackUserData*>(userData);
124     auto codecServer = callbackUserData->codecServer;
125     CHECK_AND_RETURN_LOG(codecServer != nullptr, "Codec server dose not exit");
126     codecServer->PostProcessingOnError(errorCode);
127 }
128 
PostProcessingCallbackOnOutputBufferAvailable(uint32_t index,int32_t flag,void * userData)129 void PostProcessingCallbackOnOutputBufferAvailable(uint32_t index, int32_t flag, void* userData)
130 {
131     CHECK_AND_RETURN_LOG(userData != nullptr, "Post processing callback's userData is nullptr");
132     auto callbackUserData = static_cast<PostProcessingCallbackUserData*>(userData);
133     auto codecServer = callbackUserData->codecServer;
134     CHECK_AND_RETURN_LOG(codecServer != nullptr, "Codec server dose not exit");
135     codecServer->PostProcessingOnOutputBufferAvailable(index, flag);
136 }
137 
PostProcessingCallbackOnOutputFormatChanged(const OHOS::Media::Format & format,void * userData)138 void PostProcessingCallbackOnOutputFormatChanged(const OHOS::Media::Format& format, void* userData)
139 {
140     CHECK_AND_RETURN_LOG(userData != nullptr, "Post processing callback's userData is nullptr");
141     auto callbackUserData = static_cast<PostProcessingCallbackUserData *>(userData);
142     auto codecServer = callbackUserData->codecServer;
143     CHECK_AND_RETURN_LOG(codecServer != nullptr, "Codec server dose not exit");
144     codecServer->PostProcessingOnOutputFormatChanged(format);
145 }
146 } // namespace
147 
148 namespace OHOS {
149 namespace MediaAVCodec {
150 using namespace Media;
Create(int32_t instanceId)151 std::shared_ptr<ICodecService> CodecServer::Create(int32_t instanceId)
152 {
153     std::shared_ptr<CodecServer> server = std::make_shared<CodecServer>();
154 
155     int32_t ret = server->InitServer(instanceId);
156     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, nullptr, "Server init failed, ret: %{public}d!", ret);
157     return server;
158 }
159 
CodecServer()160 CodecServer::CodecServer()
161 {
162     AVCODEC_LOGD_WITH_TAG("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
163 }
164 
~CodecServer()165 CodecServer::~CodecServer()
166 {
167     codecBase_ = nullptr;
168     shareBufCallback_ = nullptr;
169     avBufCallback_ = nullptr;
170     (void)mallopt(M_FLUSH_THREAD_CACHE, 0);
171 
172     AVCODEC_LOGD_WITH_TAG("0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
173 }
174 
InitServer(int32_t instanceId)175 int32_t CodecServer::InitServer(int32_t instanceId)
176 {
177     instanceId_ = instanceId;
178     return AVCS_ERR_OK;
179 }
180 
Init(AVCodecType type,bool isMimeType,const std::string & name,Meta & callerInfo,API_VERSION apiVersion)181 int32_t CodecServer::Init(AVCodecType type, bool isMimeType, const std::string &name,
182                           Meta &callerInfo, API_VERSION apiVersion)
183 {
184     std::lock_guard<std::shared_mutex> lock(mutex_);
185     (void)mallopt(M_SET_THREAD_CACHE, M_THREAD_CACHE_DISABLE);
186     (void)mallopt(M_DELAYED_FREE, M_DELAYED_FREE_DISABLE);
187     codecType_ = type;
188     codecName_ = name;
189     codecMime_ = isMimeType ? name : CodecAbilitySingleton::GetInstance().GetMimeByCodecName(name);
190     int32_t ret = isMimeType ? InitByMime(callerInfo, apiVersion) : InitByName(callerInfo, apiVersion);
191     CHECK_AND_RETURN_RET_LOG_WITH_TAG(ret == AVCS_ERR_OK, ret,
192                                       "Init failed. isMimeType:(%{public}d), name:(%{public}s), error:(%{public}d)",
193                                       isMimeType, name.c_str(), ret);
194     SetCallerInfo(callerInfo);
195     callerInfo.SetData(Tag::MEDIA_CODEC_NAME, codecName_);
196     callerInfo.SetData(EventInfoExtentedKey::INSTANCE_ID.data(), instanceId_);
197 #ifdef AVCODEC_SUPPORT_EVENT_MANAGER
198     callerInfo.SetData(EventInfoExtentedKey::CODEC_TYPE.data(), type);
199     EventManager::GetInstance().OnInstanceEvent(EventType::INSTANCE_INIT, callerInfo);
200 #endif
201     shareBufCallback_ = std::make_shared<CodecBaseCallback>(shared_from_this());
202     ret = codecBase_->SetCallback(shareBufCallback_);
203     CHECK_AND_RETURN_RET_LOG_WITH_TAG(ret == AVCS_ERR_OK, ret, "SetCallback failed");
204 
205     avBufCallback_ = std::make_shared<VCodecBaseCallback>(shared_from_this());
206     ret = codecBase_->SetCallback(avBufCallback_);
207     CHECK_AND_RETURN_RET_LOG_WITH_TAG(ret == AVCS_ERR_OK, ret, "SetCallback failed");
208     AVCODEC_LOGI_WITH_TAG("Create codec %{public}s by %{public}s success", codecName_.c_str(),
209                           (isMimeType ? "mime" : "name"));
210     StatusChanged(INITIALIZED);
211     return AVCS_ERR_OK;
212 }
213 
InitByName(Meta & callerInfo,API_VERSION apiVersion)214 int32_t CodecServer::InitByName(Meta &callerInfo, API_VERSION apiVersion)
215 {
216     int32_t ret = GetAudioCodecName(codecType_, codecName_);
217     CHECK_AND_RETURN_RET_LOG_WITH_TAG(ret == AVCS_ERR_OK, ret, "CodecName get failed");
218 
219     codecBase_ = CodecFactory::Instance().CreateCodecByName(codecName_, apiVersion);
220     CHECK_AND_RETURN_RET_LOG_WITH_TAG(codecBase_ != nullptr, AVCS_ERR_NO_MEMORY, "CodecBase is nullptr");
221     return codecBase_->Init(callerInfo);
222 }
223 
InitByMime(Meta & callerInfo,API_VERSION apiVersion)224 int32_t CodecServer::InitByMime(Meta &callerInfo, API_VERSION apiVersion)
225 {
226     int32_t ret = AVCS_ERR_NO_MEMORY;
227     bool isEncoder = (codecType_ == AVCODEC_TYPE_VIDEO_ENCODER) || (codecType_ == AVCODEC_TYPE_AUDIO_ENCODER);
228     std::vector<std::string> nameArray = CodecFactory::Instance().GetCodecNameArrayByMime(codecName_, isEncoder);
229     std::vector<std::string>::iterator iter;
230     for (iter = nameArray.begin(); iter != nameArray.end(); ++iter) {
231         ret = AVCS_ERR_NO_MEMORY;
232         codecBase_ = CodecFactory::Instance().CreateCodecByName(*iter, apiVersion);
233         CHECK_AND_CONTINUE_LOG_WITH_TAG(codecBase_ != nullptr, "Skip creation failure. name:(%{public}s)",
234                                         iter->c_str());
235         ret = codecBase_->Init(callerInfo);
236         CHECK_AND_CONTINUE_LOG_WITH_TAG(ret == AVCS_ERR_OK, "Skip initialization failure. name:(%{public}s)",
237                                         iter->c_str());
238         codecName_ = *iter;
239         break;
240     }
241     CHECK_AND_RETURN_RET_LOG_WITH_TAG(codecBase_ != nullptr, AVCS_ERR_NO_MEMORY, "CodecBase is nullptr");
242     return iter == nameArray.end() ? ret : AVCS_ERR_OK;
243 }
244 
Configure(const Format & format)245 int32_t CodecServer::Configure(const Format &format)
246 {
247     std::lock_guard<std::shared_mutex> lock(mutex_);
248     CHECK_AND_RETURN_RET_LOG_WITH_TAG(status_ == INITIALIZED, AVCS_ERR_INVALID_STATE, "In invalid state, %{public}s",
249                                       GetStatusDescription(status_).data());
250     CHECK_AND_RETURN_RET_LOG_WITH_TAG(codecBase_ != nullptr, AVCS_ERR_NO_MEMORY, "Codecbase is nullptr");
251     Format config = format;
252 
253     int32_t isSetParameterCb = 0;
254     format.GetIntValue(Tag::VIDEO_ENCODER_ENABLE_SURFACE_INPUT_CALLBACK, isSetParameterCb);
255     isSetParameterCb_ = isSetParameterCb != 0;
256 
257     int32_t paramCheckRet = AVCS_ERR_OK;
258     if (codecType_ == AVCODEC_TYPE_VIDEO_ENCODER || codecType_ == AVCODEC_TYPE_VIDEO_DECODER) {
259         auto scenario = CodecParamChecker::CheckCodecScenario(config, codecType_, codecName_);
260         CHECK_AND_RETURN_RET_LOG_WITH_TAG(scenario != std::nullopt, AVCS_ERR_INVALID_VAL,
261                                           "Failed to get codec scenario");
262         scenario_ = scenario.value();
263         paramCheckRet = CodecParamChecker::CheckConfigureValid(config, codecName_, scenario_);
264         CHECK_AND_RETURN_RET_LOG_WITH_TAG(paramCheckRet == AVCS_ERR_OK ||
265                                               paramCheckRet == AVCS_ERR_CODEC_PARAM_INCORRECT,
266                                           paramCheckRet, "Params in format is not valid");
267         CodecScenarioInit(config);
268     }
269 
270     int32_t ret = codecBase_->Configure(config);
271     if (ret != AVCS_ERR_OK) {
272         StatusChanged(ERROR);
273         return ret;
274     }
275     ret = CreatePostProcessing(config);
276     if (ret != AVCS_ERR_OK) {
277         StatusChanged(ERROR);
278         return ret;
279     }
280     StatusChanged(CONFIGURED);
281     return paramCheckRet;
282 }
283 
SetCustomBuffer(std::shared_ptr<AVBuffer> buffer)284 int32_t CodecServer::SetCustomBuffer(std::shared_ptr<AVBuffer> buffer)
285 {
286     std::lock_guard<std::shared_mutex> lock(mutex_);
287     CHECK_AND_RETURN_RET_LOG_WITH_TAG(status_ == CONFIGURED, AVCS_ERR_INVALID_STATE, "In invalid state, %{public}s",
288                                       GetStatusDescription(status_).data());
289     CHECK_AND_RETURN_RET_LOG_WITH_TAG(codecBase_ != nullptr, AVCS_ERR_NO_MEMORY, "Codecbase is nullptr");
290     return codecBase_->SetCustomBuffer(buffer);
291 }
292 
CodecScenarioInit(Format & config)293 int32_t CodecServer::CodecScenarioInit(Format &config)
294 {
295     switch (scenario_) {
296         case CodecScenario::CODEC_SCENARIO_ENC_TEMPORAL_SCALABILITY:
297             temporalScalability_ = std::make_shared<TemporalScalability>(codecName_);
298             temporalScalability_->ValidateTemporalGopParam(config);
299             if (!temporalScalability_->svcLTR_) {
300                 temporalScalability_ = nullptr;
301             } else {
302                 temporalScalability_->SetTag(this->GetTag());
303             }
304             break;
305         default:
306             break;
307     }
308 
309     return AVCS_ERR_OK;
310 }
311 
StartInputParamTask()312 void CodecServer::StartInputParamTask()
313 {
314     inputParamTask_ = std::make_shared<TaskThread>("InputParamTask");
315     std::weak_ptr<CodecServer> weakThis = weak_from_this();
316     inputParamTask_->RegisterHandler([weakThis] {
317         std::shared_ptr<CodecServer> cs = weakThis.lock();
318         if (cs) {
319             uint32_t index = cs->temporalScalability_->GetFirstBufferIndex();
320             AVCodecBufferInfo info;
321             AVCodecBufferFlag flag = AVCODEC_BUFFER_FLAG_NONE;
322             CHECK_AND_RETURN_LOG(cs->QueueInputBuffer(index, info, flag) == AVCS_ERR_OK, "QueueInputBuffer failed");
323         }
324     });
325     inputParamTask_->Start();
326 }
327 
Start()328 int32_t CodecServer::Start()
329 {
330     SetFreeStatus(false);
331     std::lock_guard<std::shared_mutex> lock(mutex_);
332     CHECK_AND_RETURN_RET_LOG_WITH_TAG(status_ == FLUSHED || status_ == CONFIGURED, AVCS_ERR_INVALID_STATE,
333                                       "In invalid state, %{public}s", GetStatusDescription(status_).data());
334     CHECK_AND_RETURN_RET_LOG_WITH_TAG(codecBase_ != nullptr, AVCS_ERR_NO_MEMORY, "Codecbase is nullptr");
335     if (temporalScalability_ != nullptr && isCreateSurface_ && !isSetParameterCb_) {
336         StartInputParamTask();
337     }
338     int32_t ret = StartPostProcessing();
339     CHECK_AND_RETURN_RET_LOG_WITH_TAG(ret == AVCS_ERR_OK, ret, "Start post processing failed");
340     ret = codecBase_->Start();
341     if (ret != AVCS_ERR_OK) {
342         (void)StopPostProcessing();
343         StatusChanged(ERROR);
344     } else {
345         StatusChanged(RUNNING);
346         isModeConfirmed_ = true;
347         CodecDfxInfo codecDfxInfo;
348         GetCodecDfxInfo(codecDfxInfo);
349         CodecStartEventWrite(codecDfxInfo);
350     }
351     OnInstanceMemoryUpdateEvent();
352     return ret;
353 }
354 
Stop()355 int32_t CodecServer::Stop()
356 {
357     SetFreeStatus(true);
358     std::lock_guard<std::shared_mutex> lock(mutex_);
359     CHECK_AND_RETURN_RET_LOGW_WITH_TAG(status_ != CONFIGURED, AVCS_ERR_OK, "Already in %{public}s state",
360                                        GetStatusDescription(status_).data());
361     CHECK_AND_RETURN_RET_LOG_WITH_TAG(status_ == RUNNING || status_ == END_OF_STREAM || status_ == FLUSHED,
362                                       AVCS_ERR_INVALID_STATE, "In invalid state, %{public}s",
363                                       GetStatusDescription(status_).data());
364     CHECK_AND_RETURN_RET_LOG_WITH_TAG(codecBase_ != nullptr, AVCS_ERR_NO_MEMORY, "Codecbase is nullptr");
365     int32_t retPostProcessing = StopPostProcessing();
366     int32_t retCodec = codecBase_->Stop();
367     CodecStopEventWrite(caller_.pid, caller_.uid, FAKE_POINTER(this));
368     if ((retPostProcessing + retCodec) != AVCS_ERR_OK) {
369         StatusChanged(ERROR);
370         return (retCodec == AVCS_ERR_OK) ? retPostProcessing : retCodec;
371     }
372     StatusChanged(CONFIGURED);
373     OnInstanceMemoryResetEvent();
374     return AVCS_ERR_OK;
375 }
376 
Flush()377 int32_t CodecServer::Flush()
378 {
379     SetFreeStatus(true);
380     std::lock_guard<std::shared_mutex> lock(mutex_);
381     CHECK_AND_RETURN_RET_LOGW_WITH_TAG(status_ != FLUSHED, AVCS_ERR_OK, "Already in %{public}s state",
382                                        GetStatusDescription(status_).data());
383     CHECK_AND_RETURN_RET_LOG_WITH_TAG(status_ == RUNNING || status_ == END_OF_STREAM, AVCS_ERR_INVALID_STATE,
384                                       "In invalid state, %{public}s", GetStatusDescription(status_).data());
385     CHECK_AND_RETURN_RET_LOG_WITH_TAG(codecBase_ != nullptr, AVCS_ERR_NO_MEMORY, "Codecbase is nullptr");
386     int32_t retPostProcessing = FlushPostProcessing();
387     int32_t retCodec = codecBase_->Flush();
388     CodecStopEventWrite(caller_.pid, caller_.uid, FAKE_POINTER(this));
389     if (retPostProcessing + retCodec != AVCS_ERR_OK) {
390         StatusChanged(ERROR);
391         return (retPostProcessing != AVCS_ERR_OK) ? retPostProcessing : retCodec;
392     }
393     StatusChanged(FLUSHED);
394     return AVCS_ERR_OK;
395 }
396 
NotifyEos()397 int32_t CodecServer::NotifyEos()
398 {
399     std::lock_guard<std::shared_mutex> lock(mutex_);
400     CHECK_AND_RETURN_RET_LOG_WITH_TAG(status_ == RUNNING, AVCS_ERR_INVALID_STATE, "In invalid state, %{public}s",
401                                       GetStatusDescription(status_).data());
402     CHECK_AND_RETURN_RET_LOG_WITH_TAG(codecBase_ != nullptr, AVCS_ERR_NO_MEMORY, "Codecbase is nullptr");
403     int32_t ret = codecBase_->NotifyEos();
404     if (ret == AVCS_ERR_OK) {
405         CodecStatus newStatus = END_OF_STREAM;
406         StatusChanged(newStatus);
407         CodecStopEventWrite(caller_.pid, caller_.uid, FAKE_POINTER(this));
408     }
409     return ret;
410 }
411 
Reset()412 int32_t CodecServer::Reset()
413 {
414     SetFreeStatus(true);
415     std::lock_guard<std::shared_mutex> lock(mutex_);
416     CHECK_AND_RETURN_RET_LOG_WITH_TAG(codecBase_ != nullptr, AVCS_ERR_NO_MEMORY, "Codecbase is nullptr");
417     drmDecryptor_ = nullptr;
418     if (temporalScalability_ != nullptr) {
419         if (inputParamTask_ != nullptr) {
420             temporalScalability_->SetBlockQueueActive();
421             inputParamTask_->Stop();
422             inputParamTask_ = nullptr;
423         }
424         temporalScalability_ = nullptr;
425     }
426     int32_t ret = codecBase_->Reset();
427     CodecStatus newStatus = (ret == AVCS_ERR_OK ? INITIALIZED : ERROR);
428     StatusChanged(newStatus);
429     ret = ReleasePostProcessing();
430     if (ret != AVCS_ERR_OK) {
431         StatusChanged(ERROR);
432     }
433     CodecStopEventWrite(caller_.pid, caller_.uid, FAKE_POINTER(this));
434     lastErrMsg_.clear();
435     if (ret == AVCS_ERR_OK) {
436         isSurfaceMode_ = false;
437         isModeConfirmed_ = false;
438     }
439     OnInstanceMemoryResetEvent();
440     return ret;
441 }
442 
Release()443 int32_t CodecServer::Release()
444 {
445     SetFreeStatus(true);
446     std::lock_guard<std::shared_mutex> lock(mutex_);
447     CHECK_AND_RETURN_RET_LOG_WITH_TAG(codecBase_ != nullptr, AVCS_ERR_NO_MEMORY, "Codecbase is nullptr");
448     drmDecryptor_ = nullptr;
449     if (temporalScalability_ != nullptr) {
450         if (inputParamTask_ != nullptr) {
451             temporalScalability_->SetBlockQueueActive();
452             inputParamTask_->Stop();
453             inputParamTask_ = nullptr;
454         }
455         temporalScalability_ = nullptr;
456     }
457     int32_t ret = codecBase_->Release();
458     CodecStopEventWrite(caller_.pid, caller_.uid, FAKE_POINTER(this));
459     codecBase_ = nullptr;
460     shareBufCallback_ = nullptr;
461     avBufCallback_ = nullptr;
462     (void)ReleasePostProcessing();
463     if (ret == AVCS_ERR_OK) {
464         isSurfaceMode_ = false;
465         isModeConfirmed_ = false;
466     }
467     return ret;
468 }
469 
CreateInputSurface()470 sptr<Surface> CodecServer::CreateInputSurface()
471 {
472     std::lock_guard<std::shared_mutex> lock(mutex_);
473     CHECK_AND_RETURN_RET_LOG_WITH_TAG(status_ == CONFIGURED, nullptr, "In invalid state, %{public}s",
474                                       GetStatusDescription(status_).data());
475     CHECK_AND_RETURN_RET_LOG_WITH_TAG(codecBase_ != nullptr, nullptr, "Codecbase is nullptr");
476     sptr<Surface> surface = codecBase_->CreateInputSurface();
477     if (surface != nullptr) {
478         isSurfaceMode_ = true;
479         isCreateSurface_ = true;
480     }
481     return surface;
482 }
483 
SetInputSurface(sptr<Surface> surface)484 int32_t CodecServer::SetInputSurface(sptr<Surface> surface)
485 {
486     std::lock_guard<std::shared_mutex> lock(mutex_);
487     CHECK_AND_RETURN_RET_LOG_WITH_TAG(status_ == CONFIGURED, AVCS_ERR_INVALID_STATE, "In invalid state, %{public}s",
488                                       GetStatusDescription(status_).data());
489     CHECK_AND_RETURN_RET_LOG_WITH_TAG(codecBase_ != nullptr, AVCS_ERR_NO_MEMORY, "Codecbase is nullptr");
490     if (surface != nullptr) {
491         isSurfaceMode_ = true;
492     }
493     return codecBase_->SetInputSurface(surface);
494 }
495 
SetOutputSurface(sptr<Surface> surface)496 int32_t CodecServer::SetOutputSurface(sptr<Surface> surface)
497 {
498     std::lock_guard<std::shared_mutex> lock(mutex_);
499     bool isBufferMode = isModeConfirmed_ && !isSurfaceMode_;
500     CHECK_AND_RETURN_RET_LOG_WITH_TAG(!isBufferMode, AVCS_ERR_INVALID_OPERATION, "In buffer mode");
501 
502     bool isValidState = isModeConfirmed_ ? isSurfaceMode_ && (status_ == CONFIGURED || status_ == RUNNING ||
503                                                               status_ == FLUSHED || status_ == END_OF_STREAM)
504                                          : status_ == CONFIGURED;
505     CHECK_AND_RETURN_RET_LOG_WITH_TAG(isValidState, AVCS_ERR_INVALID_STATE, "In invalid state, %{public}s",
506                                       GetStatusDescription(status_).data());
507     CHECK_AND_RETURN_RET_LOG_WITH_TAG(codecBase_ != nullptr, AVCS_ERR_NO_MEMORY, "Codecbase is nullptr");
508     GSError gsRet = surface->SetSurfaceSourceType(OHSurfaceSource::OH_SURFACE_SOURCE_VIDEO);
509     EXPECT_AND_LOGW_WITH_TAG(gsRet != GSERROR_OK, "Set surface source type failed, %{public}s",
510                              GSErrorStr(gsRet).c_str());
511     int32_t ret = AVCS_ERR_OK;
512     if (postProcessing_) {
513         ret = SetOutputSurfaceForPostProcessing(surface);
514     } else {
515         ret = codecBase_->SetOutputSurface(surface);
516     }
517     isSurfaceMode_ = true;
518 #ifdef EMULATOR_ENABLED
519     Format config_emulator;
520     config_emulator.PutIntValue(Tag::VIDEO_PIXEL_FORMAT, static_cast<int32_t>(VideoPixelFormat::RGBA));
521     codecBase_->SetParameter(config_emulator);
522 #endif
523     return ret;
524 }
525 
DrmVideoCencDecrypt(uint32_t index)526 int32_t CodecServer::DrmVideoCencDecrypt(uint32_t index)
527 {
528     int32_t ret = AVCS_ERR_OK;
529     if (drmDecryptor_ != nullptr) {
530         if (decryptVideoBufs_.find(index) != decryptVideoBufs_.end()) {
531             uint32_t dataSize = static_cast<uint32_t>(decryptVideoBufs_[index].inBuf->memory_->GetSize());
532             decryptVideoBufs_[index].outBuf->pts_ = decryptVideoBufs_[index].inBuf->pts_;
533             decryptVideoBufs_[index].outBuf->dts_ = decryptVideoBufs_[index].inBuf->dts_;
534             decryptVideoBufs_[index].outBuf->duration_ = decryptVideoBufs_[index].inBuf->duration_;
535             decryptVideoBufs_[index].outBuf->flag_ = decryptVideoBufs_[index].inBuf->flag_;
536             if (decryptVideoBufs_[index].inBuf->meta_ != nullptr) {
537                 *(decryptVideoBufs_[index].outBuf->meta_) = *(decryptVideoBufs_[index].inBuf->meta_);
538             }
539             if (dataSize == 0) {
540                 decryptVideoBufs_[index].outBuf->memory_->SetSize(dataSize);
541                 return ret;
542             }
543             // LCOV_EXCL_START
544             drmDecryptor_->SetCodecName(codecName_);
545             ret = drmDecryptor_->DrmVideoCencDecrypt(decryptVideoBufs_[index].inBuf, decryptVideoBufs_[index].outBuf,
546                                                      dataSize);
547             decryptVideoBufs_[index].outBuf->memory_->SetSize(dataSize);
548             // LCOV_EXCL_STOP
549         }
550     }
551     return ret;
552 }
553 
QueueInputBuffer(uint32_t index,AVCodecBufferInfo info,AVCodecBufferFlag flag)554 int32_t CodecServer::QueueInputBuffer(uint32_t index, AVCodecBufferInfo info, AVCodecBufferFlag flag)
555 {
556     std::shared_lock<std::shared_mutex> freeLock(freeMutex_);
557     if (isFree_) {
558         AVCODEC_LOGE_WITH_TAG("In invalid state, free out");
559         return AVCS_ERR_INVALID_STATE;
560     }
561 
562     int32_t ret = AVCS_ERR_OK;
563     if (flag & AVCODEC_BUFFER_FLAG_EOS) {
564         std::lock_guard<std::shared_mutex> lock(mutex_);
565         ret = QueueInputBufferIn(index, info, flag);
566         if (ret == AVCS_ERR_OK) {
567             CodecStatus newStatus = END_OF_STREAM;
568             StatusChanged(newStatus);
569         }
570     } else {
571         std::shared_lock<std::shared_mutex> lock(mutex_);
572         ret = QueueInputBufferIn(index, info, flag);
573     }
574     return ret;
575 }
576 
QueueInputBufferIn(uint32_t index,AVCodecBufferInfo info,AVCodecBufferFlag flag)577 int32_t CodecServer::QueueInputBufferIn(uint32_t index, AVCodecBufferInfo info, AVCodecBufferFlag flag)
578 {
579     int32_t ret = AVCS_ERR_OK;
580     CHECK_AND_RETURN_RET_LOG_WITH_TAG(
581         status_ == RUNNING || ((isSetParameterCb_ || inputParamTask_ != nullptr) && status_ == END_OF_STREAM),
582         AVCS_ERR_INVALID_STATE, "In invalid state, %{public}s", GetStatusDescription(status_).data());
583     CHECK_AND_RETURN_RET_LOG_WITH_TAG(codecBase_ != nullptr, AVCS_ERR_NO_MEMORY, "Codecbase is nullptr");
584     if (temporalScalability_ != nullptr) {
585         temporalScalability_->ConfigureLTR(index);
586     }
587     if (videoCb_ != nullptr) {
588         ret = DrmVideoCencDecrypt(index);
589         CHECK_AND_RETURN_RET_LOG_WITH_TAG(ret == AVCS_ERR_OK, AVCS_ERR_DECRYPT_FAILED, "CodecServer decrypt failed");
590         ret = codecBase_->QueueInputBuffer(index);
591     }
592     if (codecCb_ != nullptr) {
593         ret = codecBase_->QueueInputBuffer(index, info, flag);
594     }
595     return ret;
596 }
597 
QueueInputBuffer(uint32_t index)598 int32_t CodecServer::QueueInputBuffer(uint32_t index)
599 {
600     (void)index;
601     return AVCS_ERR_UNSUPPORT;
602 }
603 
QueueInputParameter(uint32_t index)604 int32_t CodecServer::QueueInputParameter(uint32_t index)
605 {
606     (void)index;
607     return AVCS_ERR_UNSUPPORT;
608 }
609 
GetOutputFormat(Format & format)610 int32_t CodecServer::GetOutputFormat(Format &format)
611 {
612     std::lock_guard<std::shared_mutex> lock(mutex_);
613     CHECK_AND_RETURN_RET_LOG_WITH_TAG(status_ != UNINITIALIZED, AVCS_ERR_INVALID_STATE, "In invalid state, %{public}s",
614                                       GetStatusDescription(status_).data());
615     CHECK_AND_RETURN_RET_LOG_WITH_TAG(codecBase_ != nullptr, AVCS_ERR_NO_MEMORY, "Codecbase is nullptr");
616     if (postProcessing_) {
617         int32_t ret = codecBase_->GetOutputFormat(format);
618         CHECK_AND_RETURN_RET_LOG_WITH_TAG(ret == AVCS_ERR_OK, ret, "GetOutputFormat failed");
619         return GetPostProcessingOutputFormat(format);
620     } else {
621         return codecBase_->GetOutputFormat(format);
622     }
623 }
624 
625 // LCOV_EXCL_START
CheckDrmSvpConsistency(const sptr<DrmStandard::IMediaKeySessionService> & keySession,bool svpFlag)626 int32_t CodecServer::CheckDrmSvpConsistency(const sptr<DrmStandard::IMediaKeySessionService> &keySession,
627     bool svpFlag)
628 {
629     AVCODEC_LOGI_WITH_TAG("CheckDrmSvpConsistency");
630     CHECK_AND_RETURN_RET_LOG_WITH_TAG(keySession != nullptr, AVCS_ERR_INVALID_VAL, "keySession is nullptr");
631     std::string tmpName = codecName_;
632     transform(tmpName.begin(), tmpName.end(), tmpName.begin(), ::tolower);
633 
634     // check codec name when secure video path is false
635     if (svpFlag == false) {
636         if (tmpName.find(".secure") != std::string::npos) {
637             AVCODEC_LOGE_WITH_TAG("CheckDrmSvpConsistency failed, svpFlag is false but the decoder is secure!");
638             return AVCS_ERR_INVALID_VAL;
639         }
640         return AVCS_ERR_OK;
641     }
642 
643     // check codec name when secure video path is true
644     if (tmpName.find(".secure") == std::string::npos) {
645         AVCODEC_LOGE_WITH_TAG("CheckDrmSvpConsistency failed, svpFlag is true but the decoder is not secure!");
646         return AVCS_ERR_INVALID_VAL;
647     }
648 
649     // check session level when secure video path is true
650 #ifdef SUPPORT_DRM
651     DrmStandard::IMediaKeySessionService::ContentProtectionLevel sessionLevel;
652     int ret = keySession->GetContentProtectionLevel(&sessionLevel);
653     CHECK_AND_RETURN_RET_LOG_WITH_TAG(ret == 0, AVCS_ERR_INVALID_VAL, "GetContentProtectionLevel failed");
654     if (sessionLevel <
655         DrmStandard::IMediaKeySessionService::ContentProtectionLevel::CONTENT_PROTECTION_LEVEL_HW_CRYPTO) {
656         AVCODEC_LOGE("CheckDrmSvpConsistency failed, key session's content protection level is too low!");
657         return AVCS_ERR_INVALID_VAL;
658     }
659 #endif
660 
661     return AVCS_ERR_OK;
662 }
663 // LCOV_EXCL_STOP
664 
665 #ifdef SUPPORT_DRM
SetDecryptConfig(const sptr<DrmStandard::IMediaKeySessionService> & keySession,const bool svpFlag)666 int32_t CodecServer::SetDecryptConfig(const sptr<DrmStandard::IMediaKeySessionService> &keySession, const bool svpFlag)
667 {
668     std::lock_guard<std::shared_mutex> lock(mutex_);
669     AVCODEC_LOGI_WITH_TAG("CodecServer::SetDecryptConfig");
670     CHECK_AND_RETURN_RET_LOG_WITH_TAG(codecBase_ != nullptr, AVCS_ERR_NO_MEMORY, "Codecbase is nullptr");
671 
672     int32_t ret = CheckDrmSvpConsistency(keySession, svpFlag);
673     CHECK_AND_RETURN_RET_LOG_WITH_TAG(ret == AVCS_ERR_OK, AVCS_ERR_INVALID_VAL, "check svp failed");
674 
675     if (drmDecryptor_ == nullptr) {
676         drmDecryptor_ = std::make_shared<CodecDrmDecrypt>();
677     }
678     CHECK_AND_RETURN_RET_LOG_WITH_TAG(drmDecryptor_ != nullptr, AVCS_ERR_NO_MEMORY, "drmDecryptor is nullptr");
679     drmDecryptor_->SetDecryptionConfig(keySession, svpFlag);
680     return AVCS_ERR_OK;
681 }
682 #endif
683 
ReleaseOutputBuffer(uint32_t index,bool render)684 int32_t CodecServer::ReleaseOutputBuffer(uint32_t index, bool render)
685 {
686     std::shared_lock<std::shared_mutex> freeLock(freeMutex_);
687     if (isFree_) {
688         AVCODEC_LOGE_WITH_TAG("In invalid state, free out");
689         return AVCS_ERR_INVALID_STATE;
690     }
691     std::shared_lock<std::shared_mutex> lock(mutex_);
692     CHECK_AND_RETURN_RET_LOG_WITH_TAG(status_ == RUNNING || status_ == END_OF_STREAM, AVCS_ERR_INVALID_STATE,
693                                       "In invalid state, %{public}s", GetStatusDescription(status_).data());
694 
695     if (postProcessing_) {
696         return ReleaseOutputBufferOfPostProcessing(index, render);
697     } else {
698         return ReleaseOutputBufferOfCodec(index, render);
699     }
700 }
701 
ReleaseOutputBufferOfCodec(uint32_t index,bool render)702 int32_t CodecServer::ReleaseOutputBufferOfCodec(uint32_t index, bool render)
703 {
704     CHECK_AND_RETURN_RET_LOG_WITH_TAG(codecBase_ != nullptr, AVCS_ERR_NO_MEMORY, "Codecbase is nullptr");
705 
706     int32_t ret;
707     if (render) {
708         ret = codecBase_->RenderOutputBuffer(index);
709     } else {
710         ret = codecBase_->ReleaseOutputBuffer(index);
711     }
712     return ret;
713 }
714 
OnInstanceMemoryUpdateEvent(std::shared_ptr<Media::Meta> meta)715 void CodecServer::OnInstanceMemoryUpdateEvent(std::shared_ptr<Media::Meta> meta)
716 {
717 #ifdef AVCODEC_SUPPORT_EVENT_MANAGER
718     if (meta == nullptr) {
719         Format format;
720         (void)(codecType_ == AVCODEC_TYPE_VIDEO_DECODER ? codecBase_->GetOutputFormat(format)
721                                                         : codecBase_->GetInputFormat(format));
722         meta = format.GetMeta();
723     }
724     if (meta == nullptr) {
725         return;
726     }
727 
728     meta->SetData(EventInfoExtentedKey::CODEC_TYPE.data(), codecType_);
729     meta->SetData(EventInfoExtentedKey::INSTANCE_ID.data(), instanceId_);
730     meta->SetData(EventInfoExtentedKey::ENABLE_POST_PROCESSING.data(), postProcessing_ != nullptr);
731     meta->SetData(Media::Tag::MIME_TYPE, codecMime_);
732     EventManager::GetInstance().OnInstanceEvent(EventType::INSTANCE_MEMORY_UPDATE, *meta);
733 #endif
734 }
735 
OnInstanceMemoryResetEvent(std::shared_ptr<Media::Meta> meta)736 void CodecServer::OnInstanceMemoryResetEvent(std::shared_ptr<Media::Meta> meta)
737 {
738 #ifdef AVCODEC_SUPPORT_EVENT_MANAGER
739     if (meta == nullptr) {
740         meta = std::make_shared<Media::Meta>();
741     }
742     meta->SetData(EventInfoExtentedKey::INSTANCE_ID.data(), instanceId_);
743     EventManager::GetInstance().OnInstanceEvent(EventType::INSTANCE_MEMORY_RESET, *meta);
744 #endif
745 }
746 
RenderOutputBufferAtTime(uint32_t index,int64_t renderTimestampNs)747 int32_t CodecServer::RenderOutputBufferAtTime(uint32_t index, int64_t renderTimestampNs)
748 {
749     (void)renderTimestampNs;
750     std::shared_lock<std::shared_mutex> freeLock(freeMutex_);
751     if (isFree_) {
752         AVCODEC_LOGE_WITH_TAG("In invalid state, free out");
753         return AVCS_ERR_INVALID_STATE;
754     }
755     std::shared_lock<std::shared_mutex> lock(mutex_);
756     CHECK_AND_RETURN_RET_LOG_WITH_TAG(status_ == RUNNING || status_ == END_OF_STREAM, AVCS_ERR_INVALID_STATE,
757                                       "In invalid state, %{public}s", GetStatusDescription(status_).data());
758     CHECK_AND_RETURN_RET_LOG_WITH_TAG(codecBase_ != nullptr, AVCS_ERR_NO_MEMORY, "Codecbase is nullptr");
759     if (postProcessing_) {
760         return ReleaseOutputBufferOfPostProcessing(index, true);
761     } else {
762         return codecBase_->RenderOutputBuffer(index);
763     }
764 }
765 
SetParameter(const Format & format)766 int32_t CodecServer::SetParameter(const Format &format)
767 {
768     std::lock_guard<std::shared_mutex> lock(mutex_);
769     CHECK_AND_RETURN_RET_LOG_WITH_TAG(status_ != INITIALIZED && status_ != CONFIGURED, AVCS_ERR_INVALID_STATE,
770                                       "In invalid state, %{public}s", GetStatusDescription(status_).data());
771     CHECK_AND_RETURN_RET_LOG_WITH_TAG(codecBase_ != nullptr, AVCS_ERR_NO_MEMORY, "Codecbase is nullptr");
772 
773     if (codecType_ == AVCODEC_TYPE_VIDEO_ENCODER || codecType_ == AVCODEC_TYPE_VIDEO_DECODER) {
774         Format oldFormat;
775         int32_t ret = codecBase_->GetOutputFormat(oldFormat);
776         CHECK_AND_RETURN_RET_LOG_WITH_TAG(ret == AVCS_ERR_OK, AVCS_ERR_INVALID_OPERATION, "Failed to get codec format");
777         ret = CodecParamChecker::CheckParameterValid(format, oldFormat, codecName_, scenario_);
778         CHECK_AND_RETURN_RET_LOG_WITH_TAG(ret == AVCS_ERR_OK, ret, "Params in format is not valid");
779     }
780 
781     return codecBase_->SetParameter(format);
782 }
783 
SetCallback(const std::shared_ptr<AVCodecCallback> & callback)784 int32_t CodecServer::SetCallback(const std::shared_ptr<AVCodecCallback> &callback)
785 {
786     std::lock_guard<std::shared_mutex> cbLock(cbMutex_);
787     codecCb_ = callback;
788     return AVCS_ERR_OK;
789 }
790 
SetCallback(const std::shared_ptr<MediaCodecCallback> & callback)791 int32_t CodecServer::SetCallback(const std::shared_ptr<MediaCodecCallback> &callback)
792 {
793     std::lock_guard<std::shared_mutex> cbLock(cbMutex_);
794     videoCb_ = callback;
795     return AVCS_ERR_OK;
796 }
797 
SetCodecCallback(const std::shared_ptr<MediaCodecCallback> & codecCallback)798 int32_t CodecServer::SetCodecCallback(const std::shared_ptr<MediaCodecCallback> &codecCallback)
799 {
800     CHECK_AND_RETURN_RET_LOG(codecBase_ != nullptr, AVCS_ERR_NO_MEMORY, "Codecbase is nullptr");
801     avBufCallback_ = codecCallback;
802     return codecBase_->SetCallback(codecCallback);
803 }
804 
SetCallback(const std::shared_ptr<MediaCodecParameterCallback> & callback)805 int32_t CodecServer::SetCallback(const std::shared_ptr<MediaCodecParameterCallback> &callback)
806 {
807     (void)callback;
808     return AVCS_ERR_UNSUPPORT;
809 }
810 
SetCallback(const std::shared_ptr<MediaCodecParameterWithAttrCallback> & callback)811 int32_t CodecServer::SetCallback(const std::shared_ptr<MediaCodecParameterWithAttrCallback> &callback)
812 {
813     (void)callback;
814     return AVCS_ERR_UNSUPPORT;
815 }
816 
GetInputFormat(Format & format)817 int32_t CodecServer::GetInputFormat(Format &format)
818 {
819     std::lock_guard<std::shared_mutex> lock(mutex_);
820     CHECK_AND_RETURN_RET_LOG_WITH_TAG(
821         status_ == CONFIGURED || status_ == RUNNING || status_ == FLUSHED || status_ == END_OF_STREAM,
822         AVCS_ERR_INVALID_STATE, "In invalid state, %{public}s", GetStatusDescription(status_).data());
823     CHECK_AND_RETURN_RET_LOG_WITH_TAG(codecBase_ != nullptr, AVCS_ERR_NO_MEMORY, "Codecbase is nullptr");
824     return codecBase_->GetInputFormat(format);
825 }
826 
ChangePlugin(const std::string & mime,bool isEncoder,const std::shared_ptr<Meta> & meta)827 int32_t CodecServer::ChangePlugin(const std::string &mime, bool isEncoder, const std::shared_ptr<Meta> &meta)
828 {
829     std::lock_guard<std::shared_mutex> lock(mutex_);
830     CHECK_AND_RETURN_RET_LOG(codecBase_ != nullptr, AVCS_ERR_NO_MEMORY, "Codecbase is nullptr");
831     return codecBase_->ChangePlugin(mime, isEncoder, meta);
832 }
833 
SetDumpInfo(bool isDump,uint64_t instanceId)834 void CodecServer::SetDumpInfo(bool isDump, uint64_t instanceId)
835 {
836     CHECK_AND_RETURN_LOG(codecBase_ != nullptr, "Codecbase is nullptr");
837     return codecBase_->SetDumpInfo(isDump, instanceId);
838 }
839 
DumpInfo(int32_t fd)840 int32_t CodecServer::DumpInfo(int32_t fd)
841 {
842     CHECK_AND_RETURN_RET_LOG_WITH_TAG(fd >= 0, AVCS_ERR_OK, "Get a invalid fd");
843     CHECK_AND_RETURN_RET_LOG_WITH_TAG(codecBase_ != nullptr, AVCS_ERR_NO_MEMORY, "Codecbase is nullptr");
844     Format codecFormat;
845     int32_t ret = codecBase_->GetOutputFormat(codecFormat);
846     CHECK_AND_RETURN_RET_LOG_WITH_TAG(ret == AVCS_ERR_OK, ret, "Get codec format failed");
847 
848     AVCodecDumpControler dumpControler;
849     auto statusIt = CODEC_STATE_MAP.find(status_);
850     if (forwardCaller_.pid != -1 || !forwardCaller_.processName.empty()) {
851         dumpControler.AddInfo(DUMP_INDEX_FORWARD_CALLER_PID, "ForwardCallerPid", std::to_string(forwardCaller_.pid));
852         dumpControler.AddInfo(DUMP_INDEX_FORWARD_CALLER_PROCESS_NAME,
853             "ForwardCallerProcessName", forwardCaller_.processName);
854     }
855     dumpControler.AddInfo(DUMP_INDEX_CALLER_PID, "CallerPid", std::to_string(caller_.pid));
856     dumpControler.AddInfo(DUMP_INDEX_CALLER_PROCESS_NAME, "CallerProcessName", caller_.processName);
857     dumpControler.AddInfo(DUMP_INDEX_INSTANCE_ID, "InstanceId", std::to_string(instanceId_));
858     dumpControler.AddInfo(DUMP_INDEX_STATUS, "Status", statusIt != CODEC_STATE_MAP.end() ? statusIt->second : "");
859     dumpControler.AddInfo(DUMP_INDEX_LAST_ERROR, "LastError", lastErrMsg_.size() ? lastErrMsg_ : "Null");
860 
861     uint32_t infoIndex = 1;
862     for (auto iter : VIDEO_DUMP_TABLE) {
863         uint32_t dumpIndex = DUMP_INDEX_CODEC_INFO_START + (infoIndex++ << DUMP_OFFSET_8);
864         if (iter.first == MediaDescriptionKey::MD_KEY_PIXEL_FORMAT) {
865             dumpControler.AddInfoFromFormatWithMapping(dumpIndex, codecFormat,
866                                                        iter.first, iter.second, PIXEL_FORMAT_STRING_MAP);
867         } else if (iter.first == MediaDescriptionKey::MD_KEY_SCALE_TYPE) {
868             dumpControler.AddInfoFromFormatWithMapping(dumpIndex, codecFormat,
869                                                        iter.first, iter.second, SCALE_TYPE_STRING_MAP);
870         } else {
871             dumpControler.AddInfoFromFormat(dumpIndex, codecFormat, iter.first, iter.second);
872         }
873     }
874     std::string dumpString;
875     dumpControler.GetDumpString(dumpString);
876     dumpString += codecBase_->GetHidumperInfo();
877     write(fd, dumpString.c_str(), dumpString.size());
878     return AVCS_ERR_OK;
879 }
880 
SetCallerInfo(const Meta & callerInfo)881 void CodecServer::SetCallerInfo(const Meta &callerInfo)
882 {
883     (void)callerInfo.GetData(Tag::AV_CODEC_CALLER_PID, caller_.pid);
884     (void)callerInfo.GetData(Tag::AV_CODEC_CALLER_UID, caller_.uid);
885     (void)callerInfo.GetData(Tag::AV_CODEC_CALLER_PROCESS_NAME, caller_.processName);
886     (void)callerInfo.GetData(Tag::AV_CODEC_FORWARD_CALLER_PID, forwardCaller_.pid);
887     (void)callerInfo.GetData(Tag::AV_CODEC_FORWARD_CALLER_UID, forwardCaller_.uid);
888     (void)callerInfo.GetData(Tag::AV_CODEC_FORWARD_CALLER_PROCESS_NAME, forwardCaller_.processName);
889 
890     if (caller_.pid == -1) {
891         caller_.pid = getprocpid();
892         caller_.uid = getuid();
893     }
894 
895     EXPECT_AND_LOGI_WITH_TAG((forwardCaller_.pid >= 0) || (!forwardCaller_.processName.empty()),
896                              "Forward caller pid: %{public}d, process name: %{public}s", forwardCaller_.pid,
897                              forwardCaller_.processName.c_str());
898     AVCODEC_LOGI_WITH_TAG("Caller pid: %{public}d, process name: %{public}s", caller_.pid, caller_.processName.c_str());
899 }
900 
GetCallerInfo()901 std::shared_ptr<Media::Meta> CodecServer::GetCallerInfo()
902 {
903     auto meta = std::make_shared<Media::Meta>();
904     meta->SetData(EventInfoExtentedKey::INSTANCE_ID.data(), instanceId_);
905     meta->SetData(Tag::AV_CODEC_CALLER_PID, caller_.pid);
906     meta->SetData(Tag::AV_CODEC_FORWARD_CALLER_PID, forwardCaller_.pid);
907     return meta;
908 }
909 
GetStatusDescription(CodecStatus status)910 inline const std::string &CodecServer::GetStatusDescription(CodecStatus status)
911 {
912     if (status < UNINITIALIZED || status >= ERROR) {
913         return CODEC_STATE_MAP.at(ERROR);
914     }
915     return CODEC_STATE_MAP.at(status);
916 }
917 
StatusChanged(CodecStatus newStatus)918 inline void CodecServer::StatusChanged(CodecStatus newStatus)
919 {
920     if (status_ == newStatus) {
921         return;
922     }
923     AVCODEC_LOGI_WITH_TAG("Status %{public}s -> %{public}s", GetStatusDescription(status_).data(),
924                           GetStatusDescription(newStatus).data());
925     status_ = newStatus;
926 }
927 
OnError(int32_t errorType,int32_t errorCode)928 void CodecServer::OnError(int32_t errorType, int32_t errorCode)
929 {
930     std::lock_guard<std::shared_mutex> lock(cbMutex_);
931     lastErrMsg_ = AVCSErrorToString(static_cast<AVCodecServiceErrCode>(errorCode));
932     FaultEventWrite(FaultType::FAULT_TYPE_INNER_ERROR, lastErrMsg_, "Codec");
933     if (videoCb_ != nullptr) {
934         videoCb_->OnError(static_cast<AVCodecErrorType>(errorType), errorCode);
935     }
936     if (codecCb_ != nullptr) {
937         codecCb_->OnError(static_cast<AVCodecErrorType>(errorType), errorCode);
938     }
939 }
940 
OnOutputFormatChanged(const Format & format)941 void CodecServer::OnOutputFormatChanged(const Format &format)
942 {
943     std::lock_guard<std::shared_mutex> lock(cbMutex_);
944     if (postProcessing_) {
945         outputFormatChanged_ = format;
946         return;
947     }
948     if (videoCb_ != nullptr) {
949         videoCb_->OnOutputFormatChanged(format);
950     }
951     if (codecCb_ != nullptr) {
952         codecCb_->OnOutputFormatChanged(format);
953     }
954     auto formatTemp = format;
955     OnInstanceMemoryUpdateEvent(formatTemp.GetMeta());
956 }
957 
OnInputBufferAvailable(uint32_t index,std::shared_ptr<AVSharedMemory> buffer)958 void CodecServer::OnInputBufferAvailable(uint32_t index, std::shared_ptr<AVSharedMemory> buffer)
959 {
960     std::shared_lock<std::shared_mutex> lock(cbMutex_);
961     if (codecCb_ == nullptr || (isCreateSurface_ && !isSetParameterCb_)) {
962         return;
963     }
964     codecCb_->OnInputBufferAvailable(index, buffer);
965 }
966 
OnOutputBufferAvailable(uint32_t index,AVCodecBufferInfo info,AVCodecBufferFlag flag,std::shared_ptr<AVSharedMemory> buffer)967 void CodecServer::OnOutputBufferAvailable(uint32_t index, AVCodecBufferInfo info, AVCodecBufferFlag flag,
968                                           std::shared_ptr<AVSharedMemory> buffer)
969 {
970     std::shared_lock<std::shared_mutex> lock(cbMutex_);
971     if (codecCb_ == nullptr) {
972         return;
973     }
974     codecCb_->OnOutputBufferAvailable(index, info, flag, buffer);
975 }
976 
OnInputBufferAvailable(uint32_t index,std::shared_ptr<AVBuffer> buffer)977 void CodecServer::OnInputBufferAvailable(uint32_t index, std::shared_ptr<AVBuffer> buffer)
978 {
979     std::shared_lock<std::shared_mutex> lock(cbMutex_);
980     if (temporalScalability_ != nullptr) {
981         temporalScalability_->StoreAVBuffer(index, buffer);
982     }
983     if (videoCb_ == nullptr || (isCreateSurface_ && !isSetParameterCb_)) {
984         return;
985     }
986     if (drmDecryptor_ != nullptr) {
987         if (decryptVideoBufs_.find(index) != decryptVideoBufs_.end()) {
988             videoCb_->OnInputBufferAvailable(index, decryptVideoBufs_[index].inBuf);
989             return;
990         }
991         DrmDecryptVideoBuf decryptVideoBuf;
992         MemoryFlag memFlag = MEMORY_READ_WRITE;
993         std::shared_ptr<AVAllocator> avAllocator = AVAllocatorFactory::CreateSharedAllocator(memFlag);
994         if (avAllocator == nullptr) {
995             AVCODEC_LOGE_WITH_TAG("CreateSharedAllocator failed");
996             return;
997         }
998         decryptVideoBuf.inBuf = AVBuffer::CreateAVBuffer(avAllocator,
999             static_cast<int32_t>(buffer->memory_->GetCapacity()));
1000         if (decryptVideoBuf.inBuf == nullptr || decryptVideoBuf.inBuf->memory_ == nullptr ||
1001             decryptVideoBuf.inBuf->memory_->GetCapacity() != static_cast<int32_t>(buffer->memory_->GetCapacity())) {
1002             AVCODEC_LOGE_WITH_TAG("CreateAVBuffer failed");
1003             return;
1004         }
1005         decryptVideoBuf.outBuf = buffer;
1006         decryptVideoBufs_.insert({index, decryptVideoBuf});
1007         videoCb_->OnInputBufferAvailable(index, decryptVideoBuf.inBuf);
1008     } else {
1009         videoCb_->OnInputBufferAvailable(index, buffer);
1010     }
1011 }
1012 
OnOutputBufferAvailable(uint32_t index,std::shared_ptr<AVBuffer> buffer)1013 void CodecServer::OnOutputBufferAvailable(uint32_t index, std::shared_ptr<AVBuffer> buffer)
1014 {
1015     CHECK_AND_RETURN_LOG_WITH_TAG(buffer != nullptr, "buffer is nullptr!");
1016 
1017     if (temporalScalability_ != nullptr && !(buffer->flag_ == AVCODEC_BUFFER_FLAG_CODEC_DATA)) {
1018         temporalScalability_->SetDisposableFlag(buffer);
1019     }
1020 
1021     if (postProcessing_) {
1022         /*
1023             If post processing is configured, this callback flow is intercepted here. Just push the decoded buffer info
1024             {index, buffer} into the decodedBufferInfoQueue_ which is monitored by another task thread. Once the queue
1025             has data, the thread will pop the data from the queue and calls "CodecServer::ReleaseOutputBuffer" to flush
1026             it into video processing engine. The video processing engine will automatically processing the frame
1027             according to the index. The callback ipc proxy's function "videoCb_->OnOutputBufferAvailable" is called
1028             later in "PostProcessingOnOutputBufferAvailable" by video processing engine when the frame is processed
1029             to notify application that the frame is ready. At last, application calls
1030             "OH_VideoDecoder_RenderOutputBuffer" or "OH_VideoDecoder_FreeOutputBuffer" to flush the frame.
1031         */
1032         (void)PushDecodedBufferInfo(index, buffer);
1033     } else {
1034         std::shared_lock<std::shared_mutex> lock(cbMutex_);
1035         CHECK_AND_RETURN_LOG_WITH_TAG(videoCb_ != nullptr, "videoCb_ is nullptr!");
1036         videoCb_->OnOutputBufferAvailable(index, buffer);
1037     }
1038 }
1039 
CodecBaseCallback(const std::shared_ptr<CodecServer> & codec)1040 CodecBaseCallback::CodecBaseCallback(const std::shared_ptr<CodecServer> &codec) : codec_(codec)
1041 {
1042     AVCODEC_LOGD("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
1043 }
1044 
~CodecBaseCallback()1045 CodecBaseCallback::~CodecBaseCallback()
1046 {
1047     codec_ = nullptr;
1048     AVCODEC_LOGD("0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
1049 }
1050 
OnError(AVCodecErrorType errorType,int32_t errorCode)1051 void CodecBaseCallback::OnError(AVCodecErrorType errorType, int32_t errorCode)
1052 {
1053     if (codec_ != nullptr) {
1054         codec_->OnError(errorType, errorCode);
1055     }
1056 }
1057 
OnOutputFormatChanged(const Format & format)1058 void CodecBaseCallback::OnOutputFormatChanged(const Format &format)
1059 {
1060     if (codec_ != nullptr) {
1061         codec_->OnOutputFormatChanged(format);
1062     } else {
1063         AVCODEC_LOGI("CodecBaseCallback receive output format changed but codec is nullptr");
1064     }
1065 }
1066 
OnInputBufferAvailable(uint32_t index,std::shared_ptr<AVSharedMemory> buffer)1067 void CodecBaseCallback::OnInputBufferAvailable(uint32_t index, std::shared_ptr<AVSharedMemory> buffer)
1068 {
1069     if (codec_ != nullptr) {
1070         codec_->OnInputBufferAvailable(index, buffer);
1071     }
1072 }
1073 
OnOutputBufferAvailable(uint32_t index,AVCodecBufferInfo info,AVCodecBufferFlag flag,std::shared_ptr<AVSharedMemory> buffer)1074 void CodecBaseCallback::OnOutputBufferAvailable(uint32_t index, AVCodecBufferInfo info, AVCodecBufferFlag flag,
1075                                                 std::shared_ptr<AVSharedMemory> buffer)
1076 {
1077     if (codec_ != nullptr) {
1078         codec_->OnOutputBufferAvailable(index, info, flag, buffer);
1079     }
1080 }
1081 
VCodecBaseCallback(const std::shared_ptr<CodecServer> & codec)1082 VCodecBaseCallback::VCodecBaseCallback(const std::shared_ptr<CodecServer> &codec) : codec_(codec)
1083 {
1084     AVCODEC_LOGD("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
1085 }
1086 
~VCodecBaseCallback()1087 VCodecBaseCallback::~VCodecBaseCallback()
1088 {
1089     codec_ = nullptr;
1090     AVCODEC_LOGD("0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
1091 }
1092 
OnError(AVCodecErrorType errorType,int32_t errorCode)1093 void VCodecBaseCallback::OnError(AVCodecErrorType errorType, int32_t errorCode)
1094 {
1095     if (codec_ != nullptr) {
1096         codec_->OnError(errorType, errorCode);
1097     }
1098 }
1099 
OnOutputFormatChanged(const Format & format)1100 void VCodecBaseCallback::OnOutputFormatChanged(const Format &format)
1101 {
1102     if (codec_ != nullptr) {
1103         codec_->OnOutputFormatChanged(format);
1104     } else {
1105         AVCODEC_LOGE("receive output format changed, but codec is nullptr");
1106     }
1107 }
1108 
OnInputBufferAvailable(uint32_t index,std::shared_ptr<AVBuffer> buffer)1109 void VCodecBaseCallback::OnInputBufferAvailable(uint32_t index, std::shared_ptr<AVBuffer> buffer)
1110 {
1111     if (codec_ != nullptr) {
1112         codec_->OnInputBufferAvailable(index, buffer);
1113     }
1114 }
1115 
OnOutputBufferAvailable(uint32_t index,std::shared_ptr<AVBuffer> buffer)1116 void VCodecBaseCallback::OnOutputBufferAvailable(uint32_t index, std::shared_ptr<AVBuffer> buffer)
1117 {
1118     if (codec_ != nullptr) {
1119         codec_->OnOutputBufferAvailable(index, buffer);
1120     }
1121 }
1122 
GetCodecDfxInfo(CodecDfxInfo & codecDfxInfo)1123 int32_t CodecServer::GetCodecDfxInfo(CodecDfxInfo &codecDfxInfo)
1124 {
1125     Format format;
1126     codecBase_->GetOutputFormat(format);
1127     int32_t videoPixelFormat = static_cast<int32_t>(VideoPixelFormat::UNKNOWN);
1128     format.GetIntValue(MediaDescriptionKey::MD_KEY_PIXEL_FORMAT, videoPixelFormat);
1129     videoPixelFormat = PIXEL_FORMAT_STRING_MAP.find(videoPixelFormat) != PIXEL_FORMAT_STRING_MAP.end()
1130                            ? videoPixelFormat
1131                            : static_cast<int32_t>(VideoPixelFormat::UNKNOWN);
1132     int32_t codecIsVendor = 0;
1133     format.GetIntValue("IS_VENDOR", codecIsVendor);
1134 
1135     codecDfxInfo.clientPid = caller_.pid;
1136     codecDfxInfo.clientUid = caller_.uid;
1137     codecDfxInfo.codecInstanceId = FAKE_POINTER(this);
1138     format.GetStringValue(MediaDescriptionKey::MD_KEY_CODEC_NAME, codecDfxInfo.codecName);
1139     codecDfxInfo.codecIsVendor = codecIsVendor == 1 ? "True" : "False";
1140     codecDfxInfo.codecMode = isSurfaceMode_ ? "Surface mode" : "Buffer Mode";
1141     format.GetLongValue(MediaDescriptionKey::MD_KEY_BITRATE, codecDfxInfo.encoderBitRate);
1142     format.GetIntValue(MediaDescriptionKey::MD_KEY_WIDTH, codecDfxInfo.videoWidth);
1143     format.GetIntValue(MediaDescriptionKey::MD_KEY_HEIGHT, codecDfxInfo.videoHeight);
1144     format.GetDoubleValue(MediaDescriptionKey::MD_KEY_FRAME_RATE, codecDfxInfo.videoFrameRate);
1145     format.GetIntValue(MediaDescriptionKey::MD_KEY_CHANNEL_COUNT, codecDfxInfo.audioChannelCount);
1146     codecDfxInfo.videoPixelFormat =
1147         codecDfxInfo.audioChannelCount == 0 ? PIXEL_FORMAT_STRING_MAP.at(videoPixelFormat) : "";
1148     format.GetIntValue(MediaDescriptionKey::MD_KEY_SAMPLE_RATE, codecDfxInfo.audioSampleRate);
1149     return 0;
1150 }
1151 
Configure(const std::shared_ptr<Media::Meta> & meta)1152 int32_t CodecServer::Configure(const std::shared_ptr<Media::Meta> &meta)
1153 {
1154     std::lock_guard<std::shared_mutex> lock(mutex_);
1155     CHECK_AND_RETURN_RET_LOG_WITH_TAG(meta != nullptr, AVCS_ERR_NO_MEMORY, "Codecbase is nullptr");
1156 
1157     CHECK_AND_RETURN_RET_LOG_WITH_TAG(status_ == INITIALIZED, AVCS_ERR_INVALID_STATE, "In invalid state, %{public}s",
1158                                       GetStatusDescription(status_).data());
1159     CHECK_AND_RETURN_RET_LOG_WITH_TAG(codecBase_ != nullptr, AVCS_ERR_NO_MEMORY, "Codecbase is nullptr");
1160 
1161     int32_t ret = codecBase_->Configure(meta);
1162 
1163     CodecStatus newStatus = (ret == AVCS_ERR_OK ? CONFIGURED : ERROR);
1164     StatusChanged(newStatus);
1165     return ret;
1166 }
SetParameter(const std::shared_ptr<Media::Meta> & parameter)1167 int32_t CodecServer::SetParameter(const std::shared_ptr<Media::Meta> &parameter)
1168 {
1169     std::lock_guard<std::shared_mutex> lock(mutex_);
1170     CHECK_AND_RETURN_RET_LOG_WITH_TAG(parameter != nullptr, AVCS_ERR_NO_MEMORY, "Codecbase is nullptr");
1171     CHECK_AND_RETURN_RET_LOG_WITH_TAG(status_ != INITIALIZED && status_ != CONFIGURED, AVCS_ERR_INVALID_STATE,
1172                                       "In invalid state, %{public}s", GetStatusDescription(status_).data());
1173     return codecBase_->SetParameter(parameter);
1174 }
GetOutputFormat(std::shared_ptr<Media::Meta> & parameter)1175 int32_t CodecServer::GetOutputFormat(std::shared_ptr<Media::Meta> &parameter)
1176 {
1177     std::lock_guard<std::shared_mutex> lock(mutex_);
1178     CHECK_AND_RETURN_RET_LOG_WITH_TAG(status_ != UNINITIALIZED, AVCS_ERR_INVALID_STATE, "In invalid state, %{public}s",
1179                                       GetStatusDescription(status_).data());
1180     CHECK_AND_RETURN_RET_LOG_WITH_TAG(codecBase_ != nullptr, AVCS_ERR_NO_MEMORY, "codecBase is nullptr");
1181     return codecBase_->GetOutputFormat(parameter);
1182 }
1183 
SetOutputBufferQueue(const sptr<Media::AVBufferQueueProducer> & bufferQueueProducer)1184 int32_t CodecServer::SetOutputBufferQueue(const sptr<Media::AVBufferQueueProducer> &bufferQueueProducer)
1185 {
1186     std::lock_guard<std::shared_mutex> lock(mutex_);
1187     CHECK_AND_RETURN_RET_LOG(bufferQueueProducer != nullptr, AVCS_ERR_NO_MEMORY, "bufferQueueProducer is nullptr");
1188     CHECK_AND_RETURN_RET_LOG(codecBase_ != nullptr, AVCS_ERR_NO_MEMORY, "codecBase_ is nullptr");
1189     return codecBase_->SetOutputBufferQueue(bufferQueueProducer);
1190 }
Prepare()1191 int32_t CodecServer::Prepare()
1192 {
1193     std::lock_guard<std::shared_mutex> lock(mutex_);
1194     switch (codecType_) {
1195         case AVCODEC_TYPE_VIDEO_DECODER:
1196             // Post processing is only available for video decoder.
1197             return PreparePostProcessing();
1198         case AVCODEC_TYPE_VIDEO_ENCODER:
1199             return AVCS_ERR_OK;
1200         default:
1201             // Audio's interface "Prepare"
1202             return codecBase_->Prepare();
1203     }
1204 }
GetInputBufferQueue()1205 sptr<Media::AVBufferQueueProducer> CodecServer::GetInputBufferQueue()
1206 {
1207     std::lock_guard<std::shared_mutex> lock(mutex_);
1208     return codecBase_->GetInputBufferQueue();
1209 }
1210 
GetInputBufferQueueConsumer()1211 sptr<Media::AVBufferQueueConsumer> CodecServer::GetInputBufferQueueConsumer()
1212 {
1213     std::lock_guard<std::shared_mutex> lock(mutex_);
1214     return codecBase_ != nullptr ? codecBase_->GetInputBufferQueueConsumer() : nullptr;
1215 }
1216 
GetOutputBufferQueueProducer()1217 sptr<Media::AVBufferQueueProducer> CodecServer::GetOutputBufferQueueProducer()
1218 {
1219     std::lock_guard<std::shared_mutex> lock(mutex_);
1220     return codecBase_ != nullptr ? codecBase_->GetOutputBufferQueueProducer() : nullptr;
1221 }
1222 
ProcessInputBufferInner(bool isTriggeredByOutPort,bool isFlushed)1223 void CodecServer::ProcessInputBufferInner(bool isTriggeredByOutPort, bool isFlushed)
1224 {
1225     std::lock_guard<std::shared_mutex> lock(mutex_);
1226     CHECK_AND_RETURN_LOG(codecBase_ != nullptr, "ProcessInputBufferInner codecBase is nullptr");
1227     return codecBase_->ProcessInputBufferInner(isTriggeredByOutPort, isFlushed);
1228 }
1229 
ProcessInputBuffer()1230 void CodecServer::ProcessInputBuffer()
1231 {
1232     std::lock_guard<std::shared_mutex> lock(mutex_);
1233     return codecBase_->ProcessInputBuffer();
1234 }
1235 
1236 #ifdef SUPPORT_DRM
SetAudioDecryptionConfig(const sptr<DrmStandard::IMediaKeySessionService> & keySession,const bool svpFlag)1237 int32_t CodecServer::SetAudioDecryptionConfig(const sptr<DrmStandard::IMediaKeySessionService> &keySession,
1238                                               const bool svpFlag)
1239 {
1240     std::lock_guard<std::shared_mutex> lock(mutex_);
1241     AVCODEC_LOGI_WITH_TAG("CodecServer::SetAudioDecryptionConfig");
1242     CHECK_AND_RETURN_RET_LOG(codecBase_ != nullptr, AVCS_ERR_NO_MEMORY, "codecBase is nullptr");
1243     return codecBase_->SetAudioDecryptionConfig(keySession, svpFlag);
1244 }
1245 #endif
1246 
CheckRunning()1247 bool CodecServer::CheckRunning()
1248 {
1249     if (status_ == CodecServer::RUNNING) {
1250         return true;
1251     }
1252     return false;
1253 }
1254 
SetFreeStatus(bool isFree)1255 void CodecServer::SetFreeStatus(bool isFree)
1256 {
1257     std::lock_guard<std::shared_mutex> lock(freeMutex_);
1258     isFree_ = isFree;
1259 }
1260 
CreatePostProcessing(const Format & format)1261 int32_t CodecServer::CreatePostProcessing(const Format& format)
1262 {
1263     if (codecType_ != AVCODEC_TYPE_VIDEO_DECODER) {
1264         return AVCS_ERR_OK;
1265     }
1266     int32_t colorSpaceType;
1267     if (!format.GetIntValue(MediaDescriptionKey::MD_KEY_VIDEO_DECODER_OUTPUT_COLOR_SPACE, colorSpaceType)) {
1268         return AVCS_ERR_OK;
1269     }
1270     auto capData = CodecAbilitySingleton::GetInstance().GetCapabilityByName(codecName_);
1271     CHECK_AND_RETURN_RET_LOG_WITH_TAG(capData != std::nullopt && capData->isVendor, AVCS_ERR_UNKNOWN,
1272                                       "Get codec capability from codec list failed");
1273     CHECK_AND_RETURN_RET_LOG_WITH_TAG(codecBase_, AVCS_ERR_UNKNOWN, "Decoder is not found");
1274     int32_t ret;
1275     postProcessing_ = PostProcessingType::Create(codecBase_, format, ret);
1276     EXPECT_AND_LOGI_WITH_TAG(postProcessing_, "Post processing is configured");
1277     return ret;
1278 }
1279 
SetCallbackForPostProcessing()1280 int32_t CodecServer::SetCallbackForPostProcessing()
1281 {
1282     using namespace std::placeholders;
1283     postProcessingCallback_.onError = std::bind(PostProcessingCallbackOnError, _1, _2);
1284     postProcessingCallback_.onOutputBufferAvailable =
1285         std::bind(PostProcessingCallbackOnOutputBufferAvailable, _1, _2, _3);
1286     postProcessingCallback_.onOutputFormatChanged = std::bind(PostProcessingCallbackOnOutputFormatChanged, _1, _2);
1287     auto userData = new PostProcessingCallbackUserData;
1288     CHECK_AND_RETURN_RET_LOG_WITH_TAG(userData != nullptr, AVCS_ERR_NO_MEMORY,
1289                                       "Failed to create post processing callback userdata");
1290     userData->codecServer = shared_from_this();
1291     postProcessingUserData_ = static_cast<void *>(userData);
1292     return postProcessing_->SetCallback(postProcessingCallback_, postProcessingUserData_);
1293 }
1294 
ClearCallbackForPostProcessing()1295 void CodecServer::ClearCallbackForPostProcessing()
1296 {
1297     std::lock_guard<std::shared_mutex> lock(cbMutex_);
1298     postProcessingCallback_.onError = nullptr;
1299     postProcessingCallback_.onOutputBufferAvailable = nullptr;
1300 }
1301 
SetOutputSurfaceForPostProcessing(sptr<Surface> surface)1302 int32_t CodecServer::SetOutputSurfaceForPostProcessing(sptr<Surface> surface)
1303 {
1304     int32_t ret = postProcessing_->SetOutputSurface(surface);
1305     CHECK_AND_RETURN_RET_LOG_WITH_TAG(ret == AVCS_ERR_OK, ret, "Set output surface failed");
1306     return ret;
1307 }
1308 
PreparePostProcessing()1309 int32_t CodecServer::PreparePostProcessing()
1310 {
1311     if (!postProcessing_) {
1312         return AVCS_ERR_OK;
1313     }
1314 
1315     int32_t ret{AVCS_ERR_OK};
1316     if (postProcessingUserData_ == nullptr) {
1317         std::lock_guard<std::shared_mutex> lock(cbMutex_);
1318         ret = SetCallbackForPostProcessing();
1319         CHECK_AND_RETURN_RET_LOG_WITH_TAG(ret == AVCS_ERR_OK, ret, "Set callback for post post processing failed");
1320     }
1321 
1322     if (decodedBufferInfoQueue_ == nullptr) {
1323         decodedBufferInfoQueue_ = DecodedBufferInfoQueue::Create("DecodedBufferInfoQueue");
1324         CHECK_AND_RETURN_RET_LOG_WITH_TAG(decodedBufferInfoQueue_, AVCS_ERR_NO_MEMORY,
1325                                           "Create decoded buffer info queue failed");
1326     }
1327 
1328     if (postProcessingInputBufferInfoQueue_ == nullptr) {
1329         postProcessingInputBufferInfoQueue_ =
1330             PostProcessingBufferInfoQueue::Create("PostProcessingInputBufferInfoQueue");
1331         CHECK_AND_RETURN_RET_LOG_WITH_TAG(postProcessingInputBufferInfoQueue_, AVCS_ERR_NO_MEMORY,
1332                                           "Create post processing input buffer info queue failed");
1333     }
1334 
1335     if (postProcessingOutputBufferInfoQueue_ == nullptr) {
1336         postProcessingOutputBufferInfoQueue_ =
1337             PostProcessingBufferInfoQueue::Create("PostProcessingOutputBufferInfoQueue");
1338         CHECK_AND_RETURN_RET_LOG_WITH_TAG(postProcessingOutputBufferInfoQueue_, AVCS_ERR_NO_MEMORY,
1339                                           "Create post processing output buffer info queue failed");
1340     }
1341 
1342     ret = postProcessing_->Prepare();
1343     CHECK_AND_RETURN_RET_LOG_WITH_TAG(ret == AVCS_ERR_OK, ret, "Prepare post processing failed");
1344 
1345     AVCODEC_LOGI_WITH_TAG("Post processing is prepared");
1346     return AVCS_ERR_OK;
1347 }
1348 
StartPostProcessing()1349 int32_t CodecServer::StartPostProcessing()
1350 {
1351     if (!postProcessing_) {
1352         return AVCS_ERR_OK;
1353     }
1354     int32_t ret = postProcessing_->Start();
1355     if (ret != AVCS_ERR_OK) {
1356         StatusChanged(ERROR);
1357         return ret;
1358     }
1359     ret = StartPostProcessingTask();
1360     if (ret != AVCS_ERR_OK) {
1361         StatusChanged(ERROR);
1362         return ret;
1363     }
1364     AVCODEC_LOGI_WITH_TAG("Post processing is started");
1365     return ret;
1366 }
1367 
StopPostProcessing()1368 int32_t CodecServer::StopPostProcessing()
1369 {
1370     DeactivatePostProcessingQueue();
1371     if (postProcessingTask_) {
1372         postProcessingTask_->Stop();
1373     }
1374     if (postProcessing_) {
1375         int32_t ret = postProcessing_->Stop();
1376         CHECK_AND_RETURN_RET_LOG_WITH_TAG(ret == AVCS_ERR_OK, ret, "Stop post processing failed");
1377         AVCODEC_LOGI_WITH_TAG("Post processing is stopped");
1378     }
1379     if (decodedBufferInfoQueue_) {
1380         decodedBufferInfoQueue_->Clear();
1381     }
1382     if (postProcessingInputBufferInfoQueue_) {
1383         postProcessingInputBufferInfoQueue_->Clear();
1384     }
1385     if (postProcessingOutputBufferInfoQueue_) {
1386         postProcessingOutputBufferInfoQueue_->Clear();
1387     }
1388 
1389     decodedFrameCount_.store(0);
1390     processedFrameCount_.store(0);
1391     decoderIsEOS_.store(false);
1392     return AVCS_ERR_OK;
1393 }
1394 
FlushPostProcessing()1395 int32_t CodecServer::FlushPostProcessing()
1396 {
1397     if (!postProcessing_) {
1398         return AVCS_ERR_OK;
1399     }
1400     DeactivatePostProcessingQueue();
1401     if (postProcessingTask_) {
1402         postProcessingTask_->Pause();
1403     }
1404     auto ret = postProcessing_->Flush();
1405     if (decodedBufferInfoQueue_) {
1406         decodedBufferInfoQueue_->Clear();
1407     }
1408     if (postProcessingInputBufferInfoQueue_) {
1409         postProcessingInputBufferInfoQueue_->Clear();
1410     }
1411     if (postProcessingOutputBufferInfoQueue_) {
1412         postProcessingOutputBufferInfoQueue_->Clear();
1413     }
1414 
1415     AVCODEC_LOGD_WITH_TAG("reset frame count");
1416     decodedFrameCount_.store(0);
1417     processedFrameCount_.store(0);
1418     decoderIsEOS_.store(false);
1419 
1420     CHECK_AND_RETURN_RET_LOG_WITH_TAG(ret == AVCS_ERR_OK, ret, "Flush post processing failed");
1421     AVCODEC_LOGI_WITH_TAG("Post processing is flushed");
1422     return AVCS_ERR_OK;
1423 }
1424 
ResetPostProcessing()1425 int32_t CodecServer::ResetPostProcessing()
1426 {
1427     if (postProcessing_) {
1428         DeactivatePostProcessingQueue();
1429         if (postProcessingTask_) {
1430             postProcessingTask_->Stop();
1431         }
1432         postProcessing_->Reset();
1433         CleanPostProcessingResource();
1434         postProcessing_.reset();
1435         AVCODEC_LOGI_WITH_TAG("Post processing is reset");
1436     }
1437     return AVCS_ERR_OK;
1438 }
1439 
ReleasePostProcessing()1440 int32_t CodecServer::ReleasePostProcessing()
1441 {
1442     if (postProcessing_) {
1443         DeactivatePostProcessingQueue();
1444         if (postProcessingTask_) {
1445             postProcessingTask_->Stop();
1446         }
1447         postProcessing_->Release();
1448         CleanPostProcessingResource();
1449         postProcessing_.reset();
1450         AVCODEC_LOGI_WITH_TAG("Post processing is released");
1451     }
1452 
1453     if (postProcessingUserData_ != nullptr) {
1454         auto p = static_cast<PostProcessingCallbackUserData*>(postProcessingUserData_);
1455         p->codecServer.reset();
1456         delete p;
1457         postProcessingUserData_ = nullptr;
1458     }
1459 
1460     return AVCS_ERR_OK;
1461 }
1462 
ReleaseOutputBufferOfPostProcessing(uint32_t index,bool render)1463 int32_t CodecServer::ReleaseOutputBufferOfPostProcessing(uint32_t index, bool render)
1464 {
1465     CHECK_AND_RETURN_RET_LOG_WITH_TAG(postProcessing_, AVCS_ERR_UNKNOWN, "Post processing is null");
1466     if (index == std::numeric_limits<uint32_t>::max()) {
1467         AVCODEC_LOGD_WITH_TAG("EOS is got");
1468         return AVCS_ERR_OK;
1469     }
1470     std::shared_ptr<DecodedBufferInfo> info{nullptr};
1471     CHECK_AND_RETURN_RET_LOG(postProcessingOutputBufferInfoQueue_, AVCS_ERR_UNKNOWN, "Queue is null");
1472     auto ret = postProcessingOutputBufferInfoQueue_->PopWait(info);
1473     CHECK_AND_RETURN_RET_LOG_WITH_TAG(ret == QueueResult::OK, AVCS_ERR_UNKNOWN, "Failed to get data, %{public}s",
1474                                       QUEUE_RESULT_DESCRIPTION[static_cast<int32_t>(ret)]);
1475     CHECK_AND_RETURN_RET_LOG_WITH_TAG(info && info->buffer, AVCS_ERR_UNKNOWN, "Data is null");
1476     return postProcessing_->ReleaseOutputBuffer(index, render);
1477 }
1478 
GetPostProcessingOutputFormat(Format & format)1479 int32_t CodecServer::GetPostProcessingOutputFormat(Format& format)
1480 {
1481     postProcessing_->GetOutputFormat(format);
1482     return AVCS_ERR_OK;
1483 }
1484 
PushDecodedBufferInfo(uint32_t index,std::shared_ptr<AVBuffer> buffer)1485 int32_t CodecServer::PushDecodedBufferInfo(uint32_t index, std::shared_ptr<AVBuffer> buffer)
1486 {
1487     auto info = std::make_shared<DecodedBufferInfo>();
1488     CHECK_AND_RETURN_RET_LOG_WITH_TAG(info, AVCS_ERR_NO_MEMORY, "Failed to allocate info");
1489     info->index = index;
1490     info->buffer = std::make_shared<AVBuffer>(*buffer);
1491     CHECK_AND_RETURN_RET_LOG_WITH_TAG(decodedBufferInfoQueue_, AVCS_ERR_UNKNOWN, "Queue is null");
1492     auto ret = decodedBufferInfoQueue_->PushWait(info);
1493     CHECK_AND_RETURN_RET_LOG_WITH_TAG(ret == QueueResult::OK, AVCS_ERR_UNKNOWN, "Push data failed, %{public}s",
1494                                       QUEUE_RESULT_DESCRIPTION[static_cast<int32_t>(ret)]);
1495     return AVCS_ERR_OK;
1496 }
1497 
PostProcessingOnError(int32_t errorCode)1498 void CodecServer::PostProcessingOnError(int32_t errorCode)
1499 {
1500     std::lock_guard<std::shared_mutex> lock(cbMutex_);
1501     if (videoCb_ == nullptr) {
1502         AVCODEC_LOGD_WITH_TAG("Missing video callback");
1503         return;
1504     }
1505     int32_t ret = VPEErrorToAVCSError(errorCode);
1506     AVCODEC_LOGD_WITH_TAG("PostProcessingOnError, errorCodec:%{public}d -> %{public}d", errorCode, ret);
1507     videoCb_->OnError(AVCodecErrorType::AVCODEC_ERROR_INTERNAL, ret);
1508 }
1509 
PostProcessingOnOutputBufferAvailable(uint32_t index,int32_t flag)1510 void CodecServer::PostProcessingOnOutputBufferAvailable(uint32_t index, [[maybe_unused]] int32_t flag)
1511 {
1512     std::lock_guard<std::shared_mutex> lock(cbMutex_);
1513     if (videoCb_ == nullptr) {
1514         AVCODEC_LOGD_WITH_TAG("Missing video callback");
1515         return;
1516     }
1517     CHECK_AND_RETURN_LOG_WITH_TAG(postProcessingInputBufferInfoQueue_ && postProcessingOutputBufferInfoQueue_,
1518                                   "Queue is null");
1519     std::shared_ptr<DecodedBufferInfo> info{nullptr};
1520     auto ret = postProcessingInputBufferInfoQueue_->PopWait(info);
1521     CHECK_AND_RETURN_LOG_WITH_TAG(ret == QueueResult::OK, "Get data failed, %{public}s",
1522                                   QUEUE_RESULT_DESCRIPTION[static_cast<int32_t>(ret)]);
1523     CHECK_AND_RETURN_LOG_WITH_TAG(info && info->buffer, "Invalid data");
1524     info->index = index;
1525     ret = postProcessingOutputBufferInfoQueue_->PushWait(info);
1526     CHECK_AND_RETURN_LOG_WITH_TAG(ret == QueueResult::OK, "Push data failed, %{public}s",
1527                                   QUEUE_RESULT_DESCRIPTION[static_cast<int32_t>(ret)]);
1528     videoCb_->OnOutputBufferAvailable(index, info->buffer);
1529     processedFrameCount_++;
1530 }
1531 
PostProcessingOnOutputFormatChanged(const Format & format)1532 void CodecServer::PostProcessingOnOutputFormatChanged(const Format& format)
1533 {
1534     std::lock_guard<std::shared_mutex> lock(cbMutex_);
1535     if (videoCb_ == nullptr) {
1536         AVCODEC_LOGD_WITH_TAG("Missing video callback");
1537         return;
1538     }
1539     int32_t width = 0;
1540     if (format.GetIntValue(Media::Tag::VIDEO_WIDTH, width)) {
1541         outputFormatChanged_.PutIntValue(Media::Tag::VIDEO_WIDTH, width);
1542         outputFormatChanged_.PutIntValue(Media::Tag::VIDEO_PIC_WIDTH, width);
1543     }
1544     int32_t height = 0;
1545     if (format.GetIntValue(Media::Tag::VIDEO_HEIGHT, height)) {
1546         outputFormatChanged_.PutIntValue(Media::Tag::VIDEO_HEIGHT, height);
1547         outputFormatChanged_.PutIntValue(Media::Tag::VIDEO_PIC_HEIGHT, height);
1548     }
1549     int32_t stride = 0;
1550     if (format.GetIntValue(Media::Tag::VIDEO_STRIDE, stride)) {
1551         outputFormatChanged_.PutIntValue(Media::Tag::VIDEO_STRIDE, stride);
1552     }
1553     int32_t sliceHeight = 0;
1554     if (format.GetIntValue(Media::Tag::VIDEO_SLICE_HEIGHT, sliceHeight)) {
1555         outputFormatChanged_.PutIntValue(Media::Tag::VIDEO_SLICE_HEIGHT, sliceHeight);
1556     }
1557     int32_t outputColorSpace = 0;
1558     if (format.GetIntValue(Media::Tag::VIDEO_DECODER_OUTPUT_COLOR_SPACE, outputColorSpace)) {
1559         outputFormatChanged_.PutIntValue(Media::Tag::VIDEO_DECODER_OUTPUT_COLOR_SPACE, outputColorSpace);
1560     }
1561     videoCb_->OnOutputFormatChanged(outputFormatChanged_);
1562 }
1563 
StartPostProcessingTask()1564 int32_t CodecServer::StartPostProcessingTask()
1565 {
1566     if (!postProcessingTask_) {
1567         postProcessingTask_ = std::make_unique<TaskThread>("PostProcessing");
1568         CHECK_AND_RETURN_RET_LOG_WITH_TAG(postProcessingTask_, AVCS_ERR_UNKNOWN, "Create task post processing failed");
1569         std::function<void()> task = std::bind(&CodecServer::PostProcessingTask, this);
1570         postProcessingTask_->RegisterHandler(task);
1571     }
1572     if (decodedBufferInfoQueue_) {
1573         decodedBufferInfoQueue_->Activate();
1574     }
1575     if (postProcessingInputBufferInfoQueue_) {
1576         postProcessingInputBufferInfoQueue_->Activate();
1577     }
1578     if (postProcessingOutputBufferInfoQueue_) {
1579         postProcessingOutputBufferInfoQueue_->Activate();
1580     }
1581     postProcessingTask_->Start();
1582 
1583     return AVCS_ERR_OK;
1584 }
1585 
PostProcessingTask()1586 void CodecServer::PostProcessingTask()
1587 {
1588     CHECK_AND_RETURN_LOG_WITH_TAG(decodedBufferInfoQueue_ && postProcessingInputBufferInfoQueue_, "Queue is null");
1589     if (decoderIsEOS_.load() == false) {
1590         std::shared_ptr<DecodedBufferInfo> info{nullptr};
1591         auto ret = decodedBufferInfoQueue_->PopWait(info);
1592         CHECK_AND_RETURN_LOG_WITH_TAG(ret == QueueResult::OK, "Get data failed, %{public}s",
1593                                       QUEUE_RESULT_DESCRIPTION[static_cast<int32_t>(ret)]);
1594         CHECK_AND_RETURN_LOG_WITH_TAG(info && info->buffer, "Invalid data");
1595         ret = postProcessingInputBufferInfoQueue_->PushWait(info);
1596         CHECK_AND_RETURN_LOG_WITH_TAG(ret == QueueResult::OK, "Push data failed, %{public}s",
1597                                       QUEUE_RESULT_DESCRIPTION[static_cast<int32_t>(ret)]);
1598         decodedFrameCount_++;
1599         AVCODEC_LOGD_WITH_TAG("Decoded frame count = %{public}" PRIu64, decodedFrameCount_.load());
1600         if (info->buffer->flag_ == AVCODEC_BUFFER_FLAG_EOS) {
1601             AVCODEC_LOGI_WITH_TAG("index = %{public}u, EOS flag", info->index);
1602             decoderIsEOS_.store(true);
1603         } else {
1604             (void)ReleaseOutputBufferOfCodec(info->index, true);
1605             return;
1606         }
1607     }
1608 
1609     if (decodedFrameCount_.load() == processedFrameCount_.load() + 1) {
1610         std::shared_ptr<DecodedBufferInfo> eosInfo{nullptr};
1611         auto eosRet = postProcessingInputBufferInfoQueue_->PopWait(eosInfo);
1612         CHECK_AND_RETURN_LOG_WITH_TAG(eosRet == QueueResult::OK, "Get data failed, %{public}s",
1613                                       QUEUE_RESULT_DESCRIPTION[static_cast<int32_t>(eosRet)]);
1614         CHECK_AND_RETURN_LOG_WITH_TAG(eosInfo && eosInfo->buffer, "Invalid data");
1615         if (eosInfo->buffer->flag_ != AVCODEC_BUFFER_FLAG_EOS) {
1616             AVCODEC_LOGE("The cache info is not EOS frame");
1617             std::this_thread::sleep_for(std::chrono::seconds(1)); // 1: sleep for 1s
1618             return;
1619         }
1620         AVCODEC_LOGD_WITH_TAG("EOS flag got, frame count = %{public}" PRIu64, decodedFrameCount_.load());
1621         processedFrameCount_++;
1622         std::lock_guard<std::shared_mutex> lock(cbMutex_);
1623         if (videoCb_ == nullptr) {
1624             AVCODEC_LOGD_WITH_TAG("Missing video callback");
1625         } else {
1626             videoCb_->OnOutputBufferAvailable(std::numeric_limits<uint32_t>::max(), eosInfo->buffer);
1627             return;
1628         }
1629     } else {
1630         std::this_thread::sleep_for(std::chrono::milliseconds(20)); // 20: sleep for 20ms
1631     }
1632 }
1633 
DeactivatePostProcessingQueue()1634 void CodecServer::DeactivatePostProcessingQueue()
1635 {
1636     if (decodedBufferInfoQueue_) {
1637         decodedBufferInfoQueue_->Deactivate();
1638     }
1639     if (postProcessingInputBufferInfoQueue_) {
1640         postProcessingInputBufferInfoQueue_->Deactivate();
1641     }
1642     if (postProcessingOutputBufferInfoQueue_) {
1643         postProcessingOutputBufferInfoQueue_->Deactivate();
1644     }
1645 }
1646 
CleanPostProcessingResource()1647 void CodecServer::CleanPostProcessingResource()
1648 {
1649     ClearCallbackForPostProcessing();
1650     if (postProcessingTask_) {
1651         postProcessingTask_.reset();
1652     }
1653     if (decodedBufferInfoQueue_) {
1654         decodedBufferInfoQueue_.reset();
1655     }
1656     if (postProcessingInputBufferInfoQueue_) {
1657         postProcessingInputBufferInfoQueue_.reset();
1658     }
1659     if (postProcessingOutputBufferInfoQueue_) {
1660         postProcessingOutputBufferInfoQueue_.reset();
1661     }
1662 
1663     decodedFrameCount_.store(0);
1664     processedFrameCount_.store(0);
1665     decoderIsEOS_.store(false);
1666 }
1667 
NotifyBackGround()1668 void CodecServer::NotifyBackGround()
1669 {
1670     std::lock_guard<std::shared_mutex> lock(mutex_);
1671     CHECK_AND_RETURN_LOG(status_ == RUNNING || status_ == FLUSHED || status_ == END_OF_STREAM,
1672                          "NotifyBackGround Not need freezed, status:%{public}s", GetStatusDescription(status_).data());
1673     CHECK_AND_RETURN_LOG(codecBase_ != nullptr, "Codecbase is nullptr");
1674     int32_t ret = codecBase_->NotifyMemoryRecycle();
1675     CHECK_AND_RETURN_LOG(ret == AVCS_ERR_OK, "NotifyBackGround failed, ret:%{public}d", ret);
1676     AVCODEC_LOGI("NotifyBackGround, Caller pid: %{public}d, process name :%{public}s", caller_.pid,
1677                  caller_.processName.c_str());
1678     isFreezedFlag_ = true;
1679     return;
1680 }
1681 
NotifyForeGround()1682 void CodecServer::NotifyForeGround()
1683 {
1684     std::lock_guard<std::shared_mutex> lock(mutex_);
1685     if (isFreezedFlag_ == true) {
1686         CHECK_AND_RETURN_LOG(codecBase_ != nullptr, "Codecbase is nullptr");
1687         int32_t ret = codecBase_->NotifyMemoryWriteBack();
1688         CHECK_AND_RETURN_LOG(ret == AVCS_ERR_OK, "NotifyForeGround failed, ret:%{public}d", ret);
1689         AVCODEC_LOGI("NotifyForeGround, Caller pid: %{public}d, process name :%{public}s", caller_.pid,
1690                      caller_.processName.c_str());
1691         isFreezedFlag_ = false;
1692     }
1693     return;
1694 }
1695 } // namespace MediaAVCodec
1696 } // namespace OHOS
1697