From 41c9cfbf9af7aedfd04a569a95b2e16712f3fa02 Mon Sep 17 00:00:00 2001 From: pwx1285814 Date: Thu, 19 Sep 2024 09:47:25 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9DirtyRect=E7=9A=84=E6=88=90?= =?UTF-8?q?=E5=91=98=E5=8F=98=E9=87=8F=E7=B1=BB=E5=9E=8B=EF=BC=8C=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E5=BF=85=E8=A6=81=E7=9A=84=E6=A0=A1=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: pwx1285814 Change-Id: I1086df003da0289930817cd96201597a13be0f37 Signed-off-by: pwx1285814 --- common/include/dscreen_constants.h | 4 +- .../common/databuffer/include/data_buffer.h | 12 ++-- .../imageJpeg/include/jpeg_image_processor.h | 4 +- .../imageJpeg/src/jpeg_image_processor.cpp | 61 ++++++++++++++----- services/screenservice/sourceservice/BUILD.gn | 1 + .../src/screen_data_channel_impl.cpp | 14 ++--- 6 files changed, 64 insertions(+), 32 deletions(-) diff --git a/common/include/dscreen_constants.h b/common/include/dscreen_constants.h index 086cf4f8..5afa2ae6 100644 --- a/common/include/dscreen_constants.h +++ b/common/include/dscreen_constants.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Copyright (c) 2022-2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -210,6 +210,8 @@ constexpr float DEFAULT_DENSITY = 2.0; constexpr int32_t DEFAULT_SCREEN_FLAGS = 0; constexpr double DEFAULT_FPS = 60.0; constexpr int32_t DIRTY_MAX_SIZE = 10; +constexpr uint32_t DIRTY_MAX_BUF_SIZE = 4096; +constexpr uint32_t DIRTY_MAX_IMAGE_DATA_SIZE = 780000; constexpr uint8_t DEFAULT_CODECTYPE = VIDEO_CODEC_TYPE_VIDEO_H264; constexpr uint8_t DEFAULT_VIDEO_FORMAT = VIDEO_DATA_FORMAT_NV12; constexpr int32_t DISTRIBUTED_HARDWARE_SCREEN_SOURCE_SA_ID = 4807; diff --git a/services/common/databuffer/include/data_buffer.h b/services/common/databuffer/include/data_buffer.h index 6ce71242..baad098b 100644 --- a/services/common/databuffer/include/data_buffer.h +++ b/services/common/databuffer/include/data_buffer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Copyright (c) 2022-2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -25,11 +25,11 @@ namespace OHOS { namespace DistributedHardware { struct DirtyRect { - int32_t xPos; - int32_t yPos; - int32_t width; - int32_t height; - int32_t dirtySize; + uint32_t xPos; + uint32_t yPos; + uint32_t width; + uint32_t height; + uint32_t dirtySize; }; class DataBuffer { public: diff --git a/services/common/imageJpeg/include/jpeg_image_processor.h b/services/common/imageJpeg/include/jpeg_image_processor.h index aa6c3bad..6027a64a 100644 --- a/services/common/imageJpeg/include/jpeg_image_processor.h +++ b/services/common/imageJpeg/include/jpeg_image_processor.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * Copyright (c) 2023-2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -43,7 +43,7 @@ public: private: uint32_t CompressRgbaToJpeg(const OHOS::Rect &damage, uint8_t *inputData, uint32_t inputDataSize, std::shared_ptr &data); - void DecompressJpegToNV12(size_t jpegSize, uint8_t *inputData, uint8_t *outputData); + void DecompressJpegToNV12(size_t jpegSize, uint8_t *inputData, uint8_t *outputData, const uint32_t &outputDataSize); static const constexpr char *DSCREEN_LOG_TAG = "JpegImageProcessor"; sptr imageSurface_; diff --git a/services/common/imageJpeg/src/jpeg_image_processor.cpp b/services/common/imageJpeg/src/jpeg_image_processor.cpp index bf308036..17de8114 100644 --- a/services/common/imageJpeg/src/jpeg_image_processor.cpp +++ b/services/common/imageJpeg/src/jpeg_image_processor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * Copyright (c) 2023-2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -145,14 +145,18 @@ int32_t JpegImageProcessor::DecodeDamageData(const std::shared_ptr & DHLOGI("%{public}s: DecodeDamageData.", DSCREEN_LOG_TAG); std::vector dirtyRectVec = data->GetDirtyRectVec(); int32_t offset = 0; - int32_t screenWidth = static_cast(configParam_.GetScreenWidth()); - int32_t screenHeight = static_cast(configParam_.GetScreenHeight()); + uint32_t screenWidth = configParam_.GetScreenWidth(); + uint32_t screenHeight = configParam_.GetScreenHeight(); for (auto item : dirtyRectVec) { if (item.xPos > screenWidth || item.yPos > screenHeight || item.width > screenWidth - item.xPos || item.height > screenHeight - item.yPos) { DHLOGE("%{public}s: Dirty rect invalid.", DSCREEN_LOG_TAG); return ERR_DH_SCREEN_INPUT_PARAM_INVALID; } + if (item.dirtySize > DIRTY_MAX_BUF_SIZE) { + DHLOGE("%{public}s: Dirty rect invalid, dirtySize = %{public}" PRIu32, DSCREEN_LOG_TAG, item.dirtySize); + return ERR_DH_SCREEN_INPUT_PARAM_INVALID; + } uint8_t *jpegData = new uint8_t[item.dirtySize] {0}; int32_t ret = data->GetData(offset, item.dirtySize, jpegData); if (ret != DH_SUCCESS) { @@ -160,9 +164,16 @@ int32_t JpegImageProcessor::DecodeDamageData(const std::shared_ptr & return ret; } offset += item.dirtySize; - uint8_t *dirtyImageData = new uint8_t[item.width * item.height * RGB_CHROMA] {0}; + uint32_t dirtyImageDataSize = item.width * item.height * RGB_CHROMA; + if (dirtyImageDataSize > DIRTY_MAX_IMAGE_DATA_SIZE) { + DHLOGE("%{public}s: The dirtyImageDataSize is out of range. Expected max: %{public}" PRIu32 + ", actual: %{public}" PRIu32, DSCREEN_LOG_TAG, DIRTY_MAX_IMAGE_DATA_SIZE, dirtyImageDataSize); + delete[] jpegData; + return ERR_DH_SCREEN_INPUT_PARAM_INVALID; + } + uint8_t *dirtyImageData = new uint8_t[dirtyImageDataSize] {0}; DHLOGI("%{public}s: DecompressJpegToNV12.", DSCREEN_LOG_TAG); - DecompressJpegToNV12(item.dirtySize, jpegData, dirtyImageData); + DecompressJpegToNV12(item.dirtySize, jpegData, dirtyImageData, dirtyImageDataSize); DHLOGI("%{public}s: DecompressJpegToNV12 success.", DSCREEN_LOG_TAG); ret = ReplaceDamage2LastFrame(lastFrame, dirtyImageData, item); if (ret != DH_SUCCESS) { @@ -182,30 +193,30 @@ int32_t JpegImageProcessor::ReplaceDamage2LastFrame(uint8_t *lastFrame, uint8_t { DHLOGI("%{public}s: ReplaceDamage2LastFrame.", DSCREEN_LOG_TAG); uint8_t *lastFrameIdx = lastFrame; - uint8_t *yData = lastFrameIdx + static_cast(configParam_.GetScreenWidth() * rect.yPos + rect.xPos); + uint8_t *yData = lastFrameIdx + configParam_.GetScreenWidth() * rect.yPos + rect.xPos; uint8_t *uData = lastFrameIdx + configParam_.GetScreenWidth() * configParam_.GetScreenHeight() + - static_cast(configParam_.GetScreenWidth() * (rect.yPos / TWO) + rect.xPos); + configParam_.GetScreenWidth() * rect.yPos / TWO + rect.xPos; uint8_t *yDirtyData = dirtyImageData; uint8_t *uDirtyData = dirtyImageData + rect.width * rect.height; uint8_t *yTempData = nullptr; uint8_t *uTempData = nullptr; - for (int32_t i = 0 ; i < rect.height ; i++) { - yTempData = yData + static_cast(i) * configParam_.GetScreenWidth(); + for (uint32_t i = 0 ; i < rect.height ; i++) { + yTempData = yData + i * configParam_.GetScreenWidth(); int32_t ret = memcpy_s(yTempData, rect.width, yDirtyData, rect.width); if (ret != EOK) { DHLOGE("%{public}s: memcpy yData failed.", DSCREEN_LOG_TAG); return ret; } - yDirtyData += static_cast(rect.width); + yDirtyData += rect.width; if (i % TWO) { - uTempData = uData + configParam_.GetScreenWidth() * (static_cast(i) / TWO); + uTempData = uData + configParam_.GetScreenWidth() * i / TWO; ret = memcpy_s(uTempData, rect.width, uDirtyData, rect.width); if (ret != EOK) { DHLOGE("%{public}s: memcpy uData failed.", DSCREEN_LOG_TAG); return ret; } - uDirtyData += static_cast(rect.width); - } + uDirtyData += rect.width; + } } DHLOGI("%{public}s: ReplaceDamage2LastFrame success.", DSCREEN_LOG_TAG); return DH_SUCCESS; @@ -262,7 +273,8 @@ uint32_t JpegImageProcessor::CompressRgbaToJpeg(const OHOS::Rect &damage, return (uint32_t)outSize; } -void JpegImageProcessor::DecompressJpegToNV12(size_t jpegSize, uint8_t *inputData, uint8_t *outputData) +void JpegImageProcessor::DecompressJpegToNV12( + size_t jpegSize, uint8_t *inputData, uint8_t *outputData, const uint32_t &outputDataSize) { jpeg_decompress_struct cinfo; jpeg_error_mgr jerr; @@ -271,8 +283,25 @@ void JpegImageProcessor::DecompressJpegToNV12(size_t jpegSize, uint8_t *inputDat jpeg_mem_src(&cinfo, inputData, jpegSize); (void)jpeg_read_header(&cinfo, TRUE); (void)jpeg_start_decompress(&cinfo); - int32_t row_stride = static_cast(cinfo.output_width) * cinfo.output_components; + if ((cinfo.output_width > DSCREEN_MAX_LEN) || (cinfo.output_height > DSCREEN_MAX_LEN)) { + DHLOGE("%{public}s: JPEG image dimensions exceed DSCREEN_MAX_LEN: width = %{public}" PRIu32 + ", height = %{public}" PRIu32, DSCREEN_LOG_TAG, cinfo.output_width, cinfo.output_height); + jpeg_destroy_decompress(&cinfo); + return; + } + if (cinfo.output_components != RGB_CHROMA) { + DHLOGE("%{public}s: color components is not RGB, color components = %{public}" PRIu32, + DSCREEN_LOG_TAG, cinfo.output_components); + jpeg_destroy_decompress(&cinfo); + return; + } + uint32_t row_stride = static_cast(cinfo.output_width) * static_cast(cinfo.output_components); JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, row_stride, 1); + if (buffer == nullptr) { + DHLOGE("%{public}s: buffer is nullptr.", DSCREEN_LOG_TAG); + jpeg_destroy_decompress(&cinfo); + return; + } uint32_t uvIndex = cinfo.output_width * cinfo.output_height; int32_t i = 0; int32_t yIndex = 0; @@ -286,7 +315,7 @@ void JpegImageProcessor::DecompressJpegToNV12(size_t jpegSize, uint8_t *inputDat int32_t v = ((UB_PARAM * buffer[0][j * RGB_CHROMA] - VG_PARAM * buffer[0][j * RGB_CHROMA + 1] - VB_PARAM * buffer[0][j * RGB_CHROMA + TWO] + UA_PARAM) >> MOVEBITS) + UA_PARAM; outputData[yIndex++] = static_cast((y < 0) ? 0 : (y > YUV_PARAM) ? YUV_PARAM : y); - if ((i % TWO == 0) && (j % TWO == 0)) { + if ((i % TWO == 0) && (j % TWO == 0) && (uvIndex < outputDataSize)) { outputData[uvIndex++] = static_cast((u < 0) ? 0 : (u > YUV_PARAM) ? YUV_PARAM : u); outputData[uvIndex++] = static_cast((v < 0) ? 0 : (v > YUV_PARAM) ? YUV_PARAM : v); } diff --git a/services/screenservice/sourceservice/BUILD.gn b/services/screenservice/sourceservice/BUILD.gn index 4061c4fb..620421fd 100644 --- a/services/screenservice/sourceservice/BUILD.gn +++ b/services/screenservice/sourceservice/BUILD.gn @@ -88,6 +88,7 @@ ohos_shared_library("distributed_screen_source") { "distributed_hardware_fwk:distributed_av_sender", "distributed_hardware_fwk:distributedhardwareutils", "distributed_hardware_fwk:libdhfwk_sdk", + "eventhandler:libeventhandler", "graphic_2d:2d_graphics", "graphic_2d:libcomposer", "graphic_2d:librender_service_base", diff --git a/services/screentransport/screendatachannel/src/screen_data_channel_impl.cpp b/services/screentransport/screendatachannel/src/screen_data_channel_impl.cpp index 535eb8df..c2c5151a 100644 --- a/services/screentransport/screendatachannel/src/screen_data_channel_impl.cpp +++ b/services/screentransport/screendatachannel/src/screen_data_channel_impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Copyright (c) 2022-2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -372,7 +372,7 @@ void ScreenDataChannelImpl::JsonToDirtyJson(nlohmann::json &rectJson, std::share if (!IsInt32(rectJson, "dirtySize") || !IsInt32(rectJson, "dataType")) { return; } - int32_t dirtySize = rectJson["dirtySize"].get(); + int32_t dirtySize = rectJson["dirtySize"].get(); int32_t dataType = rectJson["dataType"].get(); int32_t num = 0; if (dirtySize >= DIRTY_MAX_SIZE) { @@ -389,11 +389,11 @@ void ScreenDataChannelImpl::JsonToDirtyJson(nlohmann::json &rectJson, std::share DHLOGE("%{public}s: JsonToDirtyJson rectJson not contain int32", DSCREEN_LOG_TAG); return; } - int32_t X = rectJson[item][KEY_POINT_DIRTY_X].get(); - int32_t Y = rectJson[item][KEY_POINT_DIRTY_Y].get(); - int32_t W = rectJson[item][KEY_POINT_DIRTY_W].get(); - int32_t H = rectJson[item][KEY_POINT_DIRTY_H].get(); - int32_t Size = rectJson[item][KEY_POINT_DIRTY_SIZE].get(); + uint32_t X = rectJson[item][KEY_POINT_DIRTY_X].get(); + uint32_t Y = rectJson[item][KEY_POINT_DIRTY_Y].get(); + uint32_t W = rectJson[item][KEY_POINT_DIRTY_W].get(); + uint32_t H = rectJson[item][KEY_POINT_DIRTY_H].get(); + uint32_t Size = rectJson[item][KEY_POINT_DIRTY_SIZE].get(); DirtyRect rect = {X, Y, W, H, Size}; screenData->AddDirtyRect(rect); num++; -- Gitee