• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023-2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "codec_server.h"
17 #include <functional>
18 #include <limits>
19 #include <malloc.h>
20 #include <map>
21 #include <unistd.h>
22 #include <vector>
23 #include "avcodec_codec_name.h"
24 #include "avcodec_dump_utils.h"
25 #include "avcodec_errors.h"
26 #include "avcodec_log.h"
27 #include "avcodec_sysevent.h"
28 #include "buffer/avbuffer.h"
29 #include "codec_ability_singleton.h"
30 #include "codec_factory.h"
31 #include "media_description.h"
32 #include "meta/meta_key.h"
33 #include "surface_type.h"
34 #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> &parameter)
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> &parameter)
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