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