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