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