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> ¶meter)
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> ¶meter)
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