1 /* 2 * Copyright (C) 2024 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 "gtest/gtest.h" 17 18 #include "image_effect_inner.h" 19 #include "efilter_factory.h" 20 #include "mock_pixel_map.h" 21 #include "brightness_efilter.h" 22 #include "contrast_efilter.h" 23 #include "test_common.h" 24 #include "external_loader.h" 25 #include "crop_efilter.h" 26 #include "mock_producer_surface.h" 27 28 using namespace testing::ext; 29 using namespace OHOS::Media::Effect; 30 31 static std::string g_jpgPath; 32 static std::string g_notJpgPath; 33 static std::string g_jpgUri; 34 static std::string g_notJpgUri; 35 36 namespace OHOS { 37 namespace Media { 38 namespace Effect { 39 namespace Test { 40 class CustomTestEFilter : public IFilterDelegate { 41 public: Render(void * efilter,EffectBuffer * src,EffectBuffer * dst,std::shared_ptr<EffectContext> & context)42 bool Render(void *efilter, EffectBuffer *src, EffectBuffer *dst, std::shared_ptr<EffectContext> &context) override 43 { 44 return true; 45 } 46 Render(void * efilter,EffectBuffer * src,std::shared_ptr<EffectContext> & context)47 bool Render(void *efilter, EffectBuffer *src, std::shared_ptr<EffectContext> &context) override 48 { 49 return true; 50 } 51 SetValue(void * efilter,const std::string & key,const Plugin::Any & value)52 bool SetValue(void *efilter, const std::string &key, const Plugin::Any &value) override 53 { 54 return true; 55 } 56 Save(void * efilter,EffectJsonPtr & res)57 bool Save(void *efilter, EffectJsonPtr &res) override 58 { 59 auto *filter = static_cast<EFilter *>(efilter); 60 return filter != nullptr && filter->Save(res) == ErrorCode::SUCCESS; 61 } 62 Restore(const EffectJsonPtr & values)63 void *Restore(const EffectJsonPtr &values) override 64 { 65 filter_ = EFilterFactory::Instance()->Create(CUSTOM_TEST_EFILTER); 66 Plugin::Any brightness = values->GetFloat("brightness"); 67 filter_->SetValue("brightness", brightness); 68 return filter_.get(); 69 } 70 GetEffectInfo()71 void *GetEffectInfo() override 72 { 73 if (info_ != nullptr) { 74 return &info_; 75 } 76 info_ = std::make_unique<EffectInfo>(); 77 info_->formats_.emplace(IEffectFormat::RGBA8888, std::vector<IPType>{ IPType::CPU }); 78 info_->category_ = Category::SHAPE_ADJUST; 79 return &info_; 80 } 81 private: 82 static std::shared_ptr<EffectInfo> info_; 83 std::shared_ptr<EFilter> filter_; 84 }; 85 std::shared_ptr<EffectInfo> CustomTestEFilter::info_ = nullptr; 86 87 class TestImageEffect : public testing::Test { 88 public: 89 TestImageEffect() = default; 90 91 ~TestImageEffect() override = default; 92 SetUpTestCase()93 static void SetUpTestCase() 94 { 95 g_jpgPath = std::string("/data/test/resource/image_effect_test1.jpg"); 96 g_notJpgPath = std::string("/data/test/resource/image_effect_test2.png"); 97 g_jpgUri = std::string("file:///data/test/resource/image_effect_test1.jpg"); 98 g_notJpgUri = std::string("file:///data/test/resource/image_effect_test2.png"); 99 } 100 TearDownTestCase()101 static void TearDownTestCase() {} 102 SetUp()103 void SetUp() override 104 { 105 mockPixelMap_ = new MockPixelMap(); 106 imageEffect_ = new ImageEffect(); 107 ExternLoader::Instance()->InitExt(); 108 EFilterFactory::Instance()->functions_.clear(); 109 EFilterFactory::Instance()->RegisterEFilter<BrightnessEFilter>(BRIGHTNESS_EFILTER); 110 EFilterFactory::Instance()->RegisterEFilter<ContrastEFilter>(CONTRAST_EFILTER); 111 EFilterFactory::Instance()->RegisterEFilter<CropEFilter>(CROP_EFILTER); 112 } 113 TearDown()114 void TearDown() override 115 { 116 delete mockPixelMap_; 117 mockPixelMap_ = nullptr; 118 delete imageEffect_; 119 imageEffect_ = nullptr; 120 } 121 PixelMap *mockPixelMap_ = nullptr; 122 ImageEffect *imageEffect_ = nullptr; 123 }; 124 125 HWTEST_F(TestImageEffect, AddEfilter001, TestSize.Level1) 126 { 127 std::shared_ptr<ImageEffect> imageEffect = std::make_unique<ImageEffect>(IMAGE_EFFECT_NAME); 128 std::shared_ptr<EFilter> brightnessEFilter = EFilterFactory::Instance()->Create(BRIGHTNESS_EFILTER); 129 imageEffect->AddEFilter(brightnessEFilter); 130 ASSERT_EQ(imageEffect->efilters_.size(), 1); 131 ASSERT_EQ(imageEffect->efilters_.at(0), brightnessEFilter); 132 133 std::shared_ptr<EFilter> cropEFilter1 = EFilterFactory::Instance()->Create(CROP_EFILTER); 134 imageEffect->AddEFilter(cropEFilter1); 135 ASSERT_EQ(imageEffect->efilters_.size(), 2); 136 ASSERT_EQ(imageEffect->efilters_.at(0), cropEFilter1); 137 ASSERT_EQ(imageEffect->efilters_.at(1), brightnessEFilter); 138 139 std::shared_ptr<EFilter> cropEFilter2 = EFilterFactory::Instance()->Create(CROP_EFILTER); 140 imageEffect->AddEFilter(cropEFilter2); 141 ASSERT_EQ(imageEffect->efilters_.size(), 3); 142 ASSERT_EQ(imageEffect->efilters_.at(0), cropEFilter1); 143 ASSERT_EQ(imageEffect->efilters_.at(1), cropEFilter2); 144 ASSERT_EQ(imageEffect->efilters_.at(2), brightnessEFilter); 145 } 146 147 HWTEST_F(TestImageEffect, Start001, TestSize.Level1) 148 { 149 std::shared_ptr<ImageEffect> imageEffect = std::make_unique<ImageEffect>(IMAGE_EFFECT_NAME); 150 std::shared_ptr<EFilter> efilter = EFilterFactory::Instance()->Create(BRIGHTNESS_EFILTER); 151 Plugin::Any value = 100.f; 152 ErrorCode result = efilter->SetValue(KEY_FILTER_INTENSITY, value); 153 ASSERT_EQ(result, ErrorCode::SUCCESS); 154 imageEffect->AddEFilter(efilter); 155 result = imageEffect->SetInputPixelMap(mockPixelMap_); 156 ASSERT_EQ(result, ErrorCode::SUCCESS); 157 result = imageEffect->SetOutputPixelMap(mockPixelMap_); 158 ASSERT_EQ(result, ErrorCode::SUCCESS); 159 result = imageEffect->Start(); 160 ASSERT_EQ(result, ErrorCode::SUCCESS); 161 } 162 163 HWTEST_F(TestImageEffect, InsertEfilter001, TestSize.Level1) 164 { 165 std::shared_ptr<ImageEffect> imageEffect = std::make_unique<ImageEffect>(IMAGE_EFFECT_NAME); 166 std::shared_ptr<EFilter> brightnessEFilter1 = EFilterFactory::Instance()->Create(BRIGHTNESS_EFILTER); 167 imageEffect->InsertEFilter(brightnessEFilter1, 0); 168 ASSERT_EQ(imageEffect->efilters_.size(), 1); 169 ASSERT_EQ(imageEffect->efilters_.at(0), brightnessEFilter1); 170 171 std::shared_ptr<EFilter> contrastEFilter = EFilterFactory::Instance()->Create(CONTRAST_EFILTER); 172 imageEffect->AddEFilter(contrastEFilter); 173 ASSERT_EQ(imageEffect->efilters_.size(), 2); 174 ASSERT_EQ(imageEffect->efilters_.at(0), brightnessEFilter1); 175 ASSERT_EQ(imageEffect->efilters_.at(1), contrastEFilter); 176 177 std::shared_ptr<EFilter> brightnessEFilter2 = EFilterFactory::Instance()->Create(BRIGHTNESS_EFILTER); 178 imageEffect->InsertEFilter(brightnessEFilter2, 1); 179 ASSERT_EQ(imageEffect->efilters_.size(), 3); 180 ASSERT_EQ(imageEffect->efilters_.at(0), brightnessEFilter1); 181 ASSERT_EQ(imageEffect->efilters_.at(1), brightnessEFilter2); 182 ASSERT_EQ(imageEffect->efilters_.at(2), contrastEFilter); 183 } 184 185 HWTEST_F(TestImageEffect, InsertEfilter002, TestSize.Level1) 186 { 187 std::shared_ptr<ImageEffect> imageEffect = std::make_unique<ImageEffect>(IMAGE_EFFECT_NAME); 188 std::shared_ptr<EFilter> brightnessEFilter1 = EFilterFactory::Instance()->Create(BRIGHTNESS_EFILTER); 189 ErrorCode result = imageEffect->InsertEFilter(brightnessEFilter1, 1); 190 ASSERT_NE(result, ErrorCode::SUCCESS); 191 } 192 193 /** 194 * Feature: ImageEffect 195 * Function: Test ImageEffect::SetInputPath with normal param 196 * SubFunction: NA 197 * FunctionPoints: NA 198 * EnvConditions: NA 199 * CaseDescription: Test ImageEffect::SetInputPath with normal param 200 */ 201 HWTEST_F(TestImageEffect, SetInputPath001, TestSize.Level1) 202 { 203 ErrorCode result = imageEffect_->SetInputPath(g_jpgPath); 204 ASSERT_EQ(result, ErrorCode::SUCCESS); 205 } 206 207 /** 208 * Feature: ImageEffect 209 * Function: Test ImageEffect::SetInputPath with nullptr param 210 * SubFunction: NA 211 * FunctionPoints: NA 212 * EnvConditions: NA 213 * CaseDescription: Test ImageEffect::SetInputPath with nullptr param 214 */ 215 HWTEST_F(TestImageEffect, SetInputPath002, TestSize.Level1) 216 { 217 ErrorCode result = imageEffect_->SetInputPath(nullptr); 218 ASSERT_NE(result, ErrorCode::SUCCESS); 219 } 220 221 /** 222 * Feature: ImageEffect 223 * Function: Test ImageEffect::SetInputPath with not support type param 224 * SubFunction: NA 225 * FunctionPoints: NA 226 * EnvConditions: NA 227 * CaseDescription: Test ImageEffect::SetInputPath with not support type param 228 */ 229 HWTEST_F(TestImageEffect, SetInputPath003, TestSize.Level1) 230 { 231 ErrorCode result = imageEffect_->SetInputPath(g_notJpgPath); 232 ASSERT_NE(result, ErrorCode::SUCCESS); 233 } 234 235 /** 236 * Feature: ImageEffect 237 * Function: Test ImageEffect::SetOutputPath with normal param 238 * SubFunction: NA 239 * FunctionPoints: NA 240 * EnvConditions: NA 241 * CaseDescription: Test ImageEffect::SetOutputPath with normal param 242 */ 243 HWTEST_F(TestImageEffect, SetOutputPath001, TestSize.Level1) 244 { 245 ErrorCode result = imageEffect_->SetOutputPath(g_jpgPath); 246 ASSERT_EQ(result, ErrorCode::SUCCESS); 247 } 248 249 /** 250 * Feature: ImageEffect 251 * Function: Test ImageEffect::SetOutputPath with nullptr param 252 * SubFunction: NA 253 * FunctionPoints: NA 254 * EnvConditions: NA 255 * CaseDescription: Test ImageEffect::SetOutputPath with nullptr param 256 */ 257 HWTEST_F(TestImageEffect, SetOutputPath002, TestSize.Level1) 258 { 259 ErrorCode result = imageEffect_->SetOutputPath(nullptr); 260 ASSERT_EQ(result, ErrorCode::SUCCESS); 261 } 262 263 /** 264 * Feature: ImageEffect 265 * Function: Test ImageEffect::SetOutputPath with not support type param 266 * SubFunction: NA 267 * FunctionPoints: NA 268 * EnvConditions: NA 269 * CaseDescription: Test ImageEffect::SetOutputPath with not support type param 270 */ 271 HWTEST_F(TestImageEffect, SetOutputPath003, TestSize.Level1) 272 { 273 ErrorCode result = imageEffect_->SetOutputPath(g_notJpgPath); 274 ASSERT_NE(result, ErrorCode::SUCCESS); 275 } 276 277 /** 278 * Feature: ImageEffect 279 * Function: Test ImageEffect::SetInputUri with normal param 280 * SubFunction: NA 281 * FunctionPoints: NA 282 * EnvConditions: NA 283 * CaseDescription: Test ImageEffect::SetInputUri with normal param 284 */ 285 HWTEST_F(TestImageEffect, SetInputUri001, TestSize.Level1) 286 { 287 ErrorCode result = imageEffect_->SetInputUri(g_jpgUri); 288 ASSERT_EQ(result, ErrorCode::SUCCESS); 289 } 290 291 /** 292 * Feature: ImageEffect 293 * Function: Test ImageEffect::SetInputUri with nullptr param 294 * SubFunction: NA 295 * FunctionPoints: NA 296 * EnvConditions: NA 297 * CaseDescription: Test ImageEffect::SetInputUri with nullptr param 298 */ 299 HWTEST_F(TestImageEffect, SetInputUri002, TestSize.Level1) 300 { 301 ErrorCode result = imageEffect_->SetInputUri(nullptr); 302 ASSERT_NE(result, ErrorCode::SUCCESS); 303 } 304 305 /** 306 * Feature: ImageEffect 307 * Function: Test ImageEffect::SetInputUri with not support type param 308 * SubFunction: NA 309 * FunctionPoints: NA 310 * EnvConditions: NA 311 * CaseDescription: Test ImageEffect::SetInputUri with not support type param 312 */ 313 HWTEST_F(TestImageEffect, SetInputUri003, TestSize.Level1) 314 { 315 ErrorCode result = imageEffect_->SetInputUri(g_notJpgUri); 316 ASSERT_NE(result, ErrorCode::SUCCESS); 317 } 318 319 /** 320 * Feature: ImageEffect 321 * Function: Test ImageEffect::SetOutputUri with normal param 322 * SubFunction: NA 323 * FunctionPoints: NA 324 * EnvConditions: NA 325 * CaseDescription: Test ImageEffect::SetOutputUri with normal param 326 */ 327 HWTEST_F(TestImageEffect, SetOutputUri001, TestSize.Level1) 328 { 329 ErrorCode result = imageEffect_->SetOutputUri(g_jpgUri); 330 ASSERT_EQ(result, ErrorCode::SUCCESS); 331 } 332 333 /** 334 * Feature: ImageEffect 335 * Function: Test ImageEffect::SetOutputUri with nullptr param 336 * SubFunction: NA 337 * FunctionPoints: NA 338 * EnvConditions: NA 339 * CaseDescription: Test ImageEffect::SetOutputUri with nullptr param 340 */ 341 HWTEST_F(TestImageEffect, SetOutputUri002, TestSize.Level1) 342 { 343 ErrorCode result = imageEffect_->SetOutputUri(nullptr); 344 ASSERT_EQ(result, ErrorCode::SUCCESS); 345 } 346 347 /** 348 * Feature: ImageEffect 349 * Function: Test ImageEffect::SetOutputUri with not support type param 350 * SubFunction: NA 351 * FunctionPoints: NA 352 * EnvConditions: NA 353 * CaseDescription: Test ImageEffect::SetOutputUri with not support type param 354 */ 355 HWTEST_F(TestImageEffect, SetOutputUri003, TestSize.Level1) 356 { 357 ErrorCode result = imageEffect_->SetOutputUri(g_notJpgUri); 358 ASSERT_NE(result, ErrorCode::SUCCESS); 359 } 360 361 HWTEST_F(TestImageEffect, Restore001, TestSize.Level1) 362 { 363 std::string info = "{\"imageEffect\":{\"filters\":[{\"name\":\"Brightness\",\"values\":{\"FilterIntensity\":" 364 "100.0}},{\"name\":\"Contrast\",\"values\":{\"FilterIntensity\":50.0}}],\"name\":\"imageEdit\"}}"; 365 std::shared_ptr<ImageEffect> imageEffect = ImageEffect::Restore(info); 366 ASSERT_NE(imageEffect, nullptr); 367 std::vector<std::shared_ptr<EFilter>> efilters = imageEffect->GetEFilters(); 368 ASSERT_EQ(efilters.size(), 2); 369 ASSERT_STREQ(efilters.at(0)->GetName().c_str(), BRIGHTNESS_EFILTER); 370 Plugin::Any value; 371 ASSERT_EQ(efilters.at(0)->GetValue(KEY_FILTER_INTENSITY, value), ErrorCode::SUCCESS); 372 auto brightnessRatio = Plugin::AnyCast<float>(&value); 373 ASSERT_NE(brightnessRatio, nullptr); 374 ASSERT_FLOAT_EQ(*brightnessRatio, 100.f); 375 376 Plugin::Any any; 377 ASSERT_STREQ(efilters.at(1)->GetName().c_str(), CONTRAST_EFILTER); 378 ASSERT_EQ(efilters.at(1)->GetValue(KEY_FILTER_INTENSITY, any), ErrorCode::SUCCESS); 379 auto contrastRatio = Plugin::AnyCast<float>(&any); 380 ASSERT_NE(contrastRatio, nullptr); 381 ASSERT_FLOAT_EQ(*contrastRatio, 50.f); 382 } 383 384 HWTEST_F(TestImageEffect, Restore002, TestSize.Level1) 385 { 386 std::shared_ptr<IFilterDelegate> customTestEFilter = std::make_unique<CustomTestEFilter>(); 387 auto *effectInfo = static_cast<std::shared_ptr<EffectInfo> *>(customTestEFilter->GetEffectInfo()); 388 ASSERT_NE(effectInfo, nullptr); 389 EFilterFactory::Instance()->RegisterDelegate(CUSTOM_TEST_EFILTER, customTestEFilter, *effectInfo); 390 391 std::string info = "{\"imageEffect\":{\"filters\":[{\"name\":\"CustomTestEFilter\",\"values\":{\"brightness\":" 392 "60.0}},{\"name\":\"Contrast\",\"values\":{\"FilterIntensity\":50.0}}],\"name\":\"imageEdit\"}}"; 393 394 std::shared_ptr<ImageEffect> imageEffect = ImageEffect::Restore(info); 395 ASSERT_NE(imageEffect, nullptr); 396 std::vector<std::shared_ptr<EFilter>> efilters = imageEffect->GetEFilters(); 397 ASSERT_EQ(efilters.size(), 2); 398 ASSERT_STREQ(efilters.at(0)->GetName().c_str(), "CustomTestEFilter"); 399 Plugin::Any value; 400 ASSERT_EQ(efilters.at(0)->GetValue("brightness", value), ErrorCode::SUCCESS); 401 auto brightness = Plugin::AnyCast<float>(&value); 402 ASSERT_NE(brightness, nullptr); 403 ASSERT_FLOAT_EQ(*brightness, 60.f); 404 405 ErrorCode errorCode = imageEffect->SetInputPixelMap(mockPixelMap_); 406 ASSERT_EQ(errorCode, ErrorCode::SUCCESS); 407 errorCode = imageEffect->Start(); 408 ASSERT_EQ(errorCode, ErrorCode::SUCCESS); 409 } 410 411 HWTEST_F(TestImageEffect, Restore003, TestSize.Level1) 412 { 413 std::string info = "{\"imageEffect\":{\"filters\":[{\"name\":\"Crop\"}],\"name\":\"imageEdit\"}}"; 414 std::shared_ptr<ImageEffect> imageEffect = ImageEffect::Restore(info); 415 ASSERT_NE(imageEffect, nullptr); 416 std::vector<std::shared_ptr<EFilter>> efilters = imageEffect->GetEFilters(); 417 ASSERT_EQ(efilters.size(), 1); 418 ASSERT_STREQ(efilters.at(0)->GetName().c_str(), CROP_EFILTER); 419 } 420 421 HWTEST_F(TestImageEffect, Surface001, TestSize.Level1) 422 { 423 sptr<Surface> consumerSurface = Surface::CreateSurfaceAsConsumer("UnitTest"); 424 sptr<IBufferProducer> producer = consumerSurface->GetProducer(); 425 sptr<ProducerSurface> surf = new(std::nothrow) MockProducerSurface(producer); 426 surf->Init(); 427 sptr<Surface> outputSurface = surf; 428 429 ErrorCode result = imageEffect_->SetOutputSurface(outputSurface); 430 ASSERT_EQ(result, ErrorCode::SUCCESS); 431 432 sptr<Surface> inputSurface = imageEffect_->GetInputSurface(); 433 ASSERT_NE(inputSurface, nullptr); 434 435 sptr<SurfaceBuffer> surfaceBuffer; 436 sptr<SurfaceBuffer> outBuffer; 437 MockProducerSurface::AllocDmaMemory(surfaceBuffer); 438 OHOS::Rect damages; 439 int64_t timeStamp = 0; 440 441 // running without filter 442 imageEffect_->ConsumerBufferAvailable(surfaceBuffer, outBuffer, damages, timeStamp); 443 444 std::shared_ptr<EFilter> contrastEFilter = EFilterFactory::Instance()->Create(CONTRAST_EFILTER); 445 Plugin::Any value = 50.f; 446 result = contrastEFilter->SetValue(KEY_FILTER_INTENSITY, value); 447 ASSERT_EQ(result, ErrorCode::SUCCESS); 448 imageEffect_->AddEFilter(contrastEFilter); 449 450 result = imageEffect_->Start(); 451 ASSERT_EQ(result, ErrorCode::SUCCESS); 452 453 // contrast filter 454 imageEffect_->ConsumerBufferAvailable(surfaceBuffer, outBuffer, damages, timeStamp); 455 MockProducerSurface::ReleaseDmaBuffer(surfaceBuffer); 456 } 457 } // namespace Test 458 } // namespace Effect 459 } // namespace Media 460 } // namespace OHOS