diff --git a/common/BUILD.gn b/common/BUILD.gn index 9a201da31568af6c0a68481ee193fc913b68c449..65d39eed4de69b7da42a31fc419b60c5918e9e21 100644 --- a/common/BUILD.gn +++ b/common/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2022 Huawei Device Co., Ltd. +# Copyright (c) 2022-2023 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 @@ -18,13 +18,17 @@ import( ohos_shared_library("distributed_screen_utils") { include_dirs = [ + "${services_path}/common/utils/include", "//commonlibrary/c_utils/base/include", - "include", "//base/hiviewdfx/hisysevent/interfaces/native/innerkits/hisysevent/include", "//base/hiviewdfx/hitrace/interfaces/native/innerkits/include/hitrace_meter", "//third_party/json/include", + "${common_path}/include", + "${fwk_common_path}/utils/include", ] + deps = [ "${distributedhardwarefwk_path}/interfaces/inner_kits:libdhfwk_sdk" ] + sources = [ "src/dscreen_hisysevent.cpp", "src/dscreen_json_util.cpp", @@ -37,6 +41,7 @@ ohos_shared_library("distributed_screen_utils") { "dsoftbus:softbus_client", "hisysevent_native:libhisysevent", "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", ] defines = [ diff --git a/common/include/dscreen_constants.h b/common/include/dscreen_constants.h index 58913e88e59c8182a25c5641bbae352438d13ebe..d071b381b1b8901d051860e76c7b9fa1dbd74073 100644 --- a/common/include/dscreen_constants.h +++ b/common/include/dscreen_constants.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-2023 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 @@ -57,11 +57,43 @@ enum VideoFormat : uint8_t { VIDEO_DATA_FORMAT_RGBA8888 = 3, }; +enum DataType : uint8_t { + VIDEO_FULL_SCREEN_DATA = 0, + VIDEO_PART_SCREEN_DATA = 1, +}; + /* Screen package name */ const std::string PKG_NAME = "ohos.dhardware.dscreen"; /* Screen data session name */ const std::string DATA_SESSION_NAME = "ohos.dhardware.dscreen.data"; +const std::string JPEG_SESSION_NAME = "ohos.dhardware.dscreen.jpeg"; +/*YUV*/ +constexpr int32_t YR_PARAM = 66; +constexpr int32_t YG_PARAM = 129; +constexpr int32_t YB_PARAM = 25; +constexpr int32_t UR_PARAM = -38; +constexpr int32_t UG_PARAM = 74; +constexpr int32_t UB_PARAM = 112; +constexpr int32_t VG_PARAM = 94; +constexpr int32_t VB_PARAM = 18; +constexpr int32_t YA_PARAM = 16; +constexpr int32_t UA_PARAM = 128; +constexpr int32_t YUV_PARAM = 255; +constexpr int32_t MOVEBITS = 8; + +/* RGBA */ +constexpr uint32_t RGBA_CHROMA = 4; +constexpr uint32_t RGB_CHROMA = 3; +constexpr uint32_t ONE = 1; +constexpr uint32_t TWO = 2; +constexpr uint32_t THREE = 3; +constexpr uint32_t ZERO = 0; +constexpr uint32_t ALIGNEDBITS = 32; + +/* Version */ +constexpr uint32_t OLD = 1; +constexpr uint32_t NEW = 2; /* Screen session name max len */ constexpr uint32_t DSCREEN_MAX_SESSION_NAME_LEN = 50; @@ -87,6 +119,7 @@ constexpr int64_t MAX_YUV420_BUFFER_SIZE = 2560 * 1600 * (3 / 2) * 2; constexpr int32_t DSCREEN_MAX_LEN = 4096; constexpr int32_t INVALID_WINDOW_ID = -1; +constexpr int32_t STRIDE_ALIGNMENT = 0x8; const std::string DSCREEN_LOG_TITLE_TAG = "DSCREEN"; const std::string DSCREEN_PREFIX = "DISTRIBUTED_SCREEN"; @@ -150,6 +183,7 @@ constexpr size_t DATA_QUEUE_MAX_SIZE = 1000; constexpr uint32_t DECODE_WAIT_MILLISECONDS = 5000; constexpr size_t DATA_BUFFER_MAX_SIZE = 10 * 1024 * 1024; constexpr uint8_t TASK_WAIT_SECONDS = 1; +constexpr int32_t JPEG_QUALITY = 80; } // namespace DistributedHardware } // namespace OHOS #endif \ No newline at end of file diff --git a/common/include/dscreen_errcode.h b/common/include/dscreen_errcode.h index 7fcc64d9d9e68d3d9c9375dd0cbc9dadbd6a3d3f..53a1ae0f290da21c18079edfcd0bde563f7c920f 100644 --- a/common/include/dscreen_errcode.h +++ b/common/include/dscreen_errcode.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-2023 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 @@ -103,6 +103,12 @@ enum DScreenErrorCode { // screen string param empty or screen input param invalid ERR_DH_SCREEN_STRING_PARAM_EMPTY = -56000, ERR_DH_SCREEN_INPUT_PARAM_INVALID = -56001, + ERR_DH_SCREEN_DATA_TYPE_INVALID = -56002, + // screen surface error + ERR_DH_SCREEN_SURFACE_REQUEST_FAILED = -57000, + ERR_DH_SCREEN_SURFACE_BUFFER_INVALIED = -57001, + ERR_DH_SCREEN_SURFACE_FLUSH_FAILED = -57002, + ERR_DH_SCREEN_SURFACE_INVALIED = -57003, }; } // namespace DistributedHardware } // namespace OHOS diff --git a/distributedscreen.gni b/distributedscreen.gni index 5c4a7ba9a939ceed4acc42bcf9ce367d84488720..e02cbb0fdf29c05bbbd6896f73455f649c0763ee 100644 --- a/distributedscreen.gni +++ b/distributedscreen.gni @@ -27,3 +27,7 @@ fwk_services_path = "${distributedhardwarefwk_path}/services" fwk_interfaces_path = "${distributedhardwarefwk_path}/interfaces" ipc_interfaces_path = "${ipc_path}/interfaces" build_flags = [ "-Werror" ] + +declare_args() { + distributed_screen_common = true +} diff --git a/interfaces/innerkits/native_cpp/test/unittest/screensourcetest/src/dscreen_source_handler_test.cpp b/interfaces/innerkits/native_cpp/test/unittest/screensourcetest/src/dscreen_source_handler_test.cpp index bc7608e86566e5cd2616b203feb52c867aa58231..47c338903dcc97407b91ad938e190e8df0144c7f 100644 --- a/interfaces/innerkits/native_cpp/test/unittest/screensourcetest/src/dscreen_source_handler_test.cpp +++ b/interfaces/innerkits/native_cpp/test/unittest/screensourcetest/src/dscreen_source_handler_test.cpp @@ -81,7 +81,7 @@ HWTEST_F(DScreenSourceHandlerTest, RegisterDistributedHardware_001, TestSize.Lev const std::string devId = "devId"; const std::string dhId = "dhId"; EnableParam param; - param.version = "1"; + param.version = "1.0"; param.attrs = "attrs"; std::string callbackParam = "callbackParam"; sptr loadCallback = new DScreenSourceLoadCallback(callbackParam); diff --git a/screenhandler/BUILD.gn b/screenhandler/BUILD.gn index 60138066eeafecc082874293326954aa46845dbc..ad0841d22f766a763ca7414e59505e2d6f06fb83 100644 --- a/screenhandler/BUILD.gn +++ b/screenhandler/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2022 Huawei Device Co., Ltd. +# Copyright (c) 2022-2023 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 diff --git a/services/common/databuffer/include/data_buffer.h b/services/common/databuffer/include/data_buffer.h index 5c34a9b5b856fdf009119a55d698394c9ee5dc26..90d7d71f5f73af356ca75d6fa436cbf163df4cea 100644 --- a/services/common/databuffer/include/data_buffer.h +++ b/services/common/databuffer/include/data_buffer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-2023 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 @@ -18,9 +18,19 @@ #include #include +#include + +#include "dscreen_constants.h" namespace OHOS { namespace DistributedHardware { +struct DirtyRect { + int32_t xPos; + int32_t yPos; + int32_t width; + int32_t height; + int32_t dirtySize; +}; class DataBuffer { public: explicit DataBuffer(size_t capacity); @@ -28,10 +38,23 @@ public: size_t Capacity() const; uint8_t *Data() const; - + void SetSize(size_t size); + void SetDataType(uint8_t dataType); + uint8_t DataType(); + void SetDataNumber(size_t number); + size_t DataNumber(); + void ResetCapcity(size_t capacity); + void AddData(size_t dataSize, unsigned char* &inputData); + void AddDirtyRect(DirtyRect rec); + std::vector GetDirtyRectVec(); + int32_t GetData(int32_t offset, int32_t datasize, uint8_t* &output); private: + static const constexpr char *LOG_TAG = "DataBuffer"; + std::vector dirtyRectVec_; size_t capacity_ = 0; uint8_t *data_ = nullptr; + uint8_t dataType_ = 0; + size_t frameNumber_ = 0; }; } // namespace DistributedHardware } // namespace OHOS diff --git a/services/common/databuffer/src/data_buffer.cpp b/services/common/databuffer/src/data_buffer.cpp index cb6b9387e396d92dc01e12035da043f717627b45..12ac906b2d378602750bbb41df255013f85a77e2 100644 --- a/services/common/databuffer/src/data_buffer.cpp +++ b/services/common/databuffer/src/data_buffer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-2023 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 @@ -15,7 +15,10 @@ #include "data_buffer.h" +#include "dscreen_errcode.h" +#include "dscreen_log.h" #include +#include namespace OHOS { namespace DistributedHardware { @@ -27,15 +30,18 @@ DataBuffer::DataBuffer(size_t capacity) capacity_ = capacity; } } + dataType_ = 0; } DataBuffer::~DataBuffer() { if (data_ != nullptr) { - delete []data_; + delete [] data_; data_ = nullptr; } - + dirtyRectVec_.clear(); + dataType_ = 0; + frameNumber_ = 0; capacity_ = 0; } @@ -48,5 +54,82 @@ uint8_t *DataBuffer::Data() const { return data_; } + +void DataBuffer::SetSize(size_t size) +{ + capacity_ = size; +} + +void DataBuffer::SetDataType(uint8_t dataType) +{ + dataType_ = dataType; +} + +uint8_t DataBuffer::DataType() +{ + return dataType_; +} + +void DataBuffer::SetDataNumber(size_t number) +{ + frameNumber_ = number; +} + +size_t DataBuffer::DataNumber() +{ + return frameNumber_; +} + +void DataBuffer::ResetCapcity(size_t capacity) +{ + DHLOGI("%s: ResetCapcity.", LOG_TAG); + if (capacity < capacity_) { + return; + } + delete [] data_; + data_ = new (std::nothrow) uint8_t[capacity] {0}; + if (data_ == nullptr) { + capacity_ = 0; + } else { + capacity_ = capacity; + } +} + +void DataBuffer::AddData(size_t dataSize, unsigned char* &inputData) +{ + if (inputData == nullptr) { + return; + } + int32_t ret = memcpy_s(data_ + capacity_, dataSize, inputData, dataSize); + if (ret != EOK) { + DHLOGE("%s: in AddData memcpy data failed, ret: %." PRId32, LOG_TAG, ret); + return; + } + capacity_ += dataSize; +} + +void DataBuffer::AddDirtyRect(DirtyRect rect) +{ + dirtyRectVec_.push_back(rect); +} + +std::vector DataBuffer::GetDirtyRectVec() +{ + return dirtyRectVec_; +} + +int32_t DataBuffer::GetData(int32_t offset, int32_t datasize, uint8_t* &output) +{ + if (offset + datasize > capacity_ || output == nullptr) { + DHLOGE("DataBuffer GetData parameter invalid."); + return ERR_DH_SCREEN_INPUT_PARAM_INVALID; + } + int32_t ret = memcpy_s(output, datasize, data_ + offset, datasize); + if (ret != EOK) { + DHLOGE("GetData memcpy data failed, ret: %." PRId32, ret); + return ret; + } + return DH_SUCCESS; +} } // namespace DistributedHardware } // namespcae OHOS \ No newline at end of file diff --git a/services/common/decision_center/include/screen_decision_center.h b/services/common/decision_center/include/screen_decision_center.h new file mode 100644 index 0000000000000000000000000000000000000000..9fa2691e416c90936c8babc686acdce08095e19a --- /dev/null +++ b/services/common/decision_center/include/screen_decision_center.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2023 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_SCREEN_DECISION_CENTER_H +#define OHOS_SCREEN_DECISION_CENTER_H + +#include + +#include "image_source_processor.h" +#include "jpeg_image_processor.h" +#include "surface_type.h" +#include "video_param.h" + +namespace OHOS { +namespace DistributedHardware { +class ScreenDecisionCenter { +public: + explicit ScreenDecisionCenter(const VideoParam &configParam) : configParam_(configParam){}; + ~ScreenDecisionCenter() = default; + bool IsDirtyRectValid(const std::vector &damages); + bool JudgeDirtyThreshold(const std::vector &damages); + bool LimitTime(uint32_t timethreshold); + int32_t InputBufferImage(sptr &surfaceBuffer, const std::vector &damages); + int32_t ConfigureDecisionCenter(std::shared_ptr &listener, + std::shared_ptr &imageProcessor); + int32_t SetJpegSurface(sptr &surface); + +private: + static const constexpr int32_t DIRTY_REGION_ARE_THRESHOLD = 260000; + static const constexpr int32_t FORCE_FULL_IMAGE_TIME_INTERAL = 10; //10 seconds + static const constexpr int32_t MIN_SURPPORT_FRAME_COUNT = 10; //10 frames + static const constexpr char *LOG_TAG = "ScreenDecisionCenter"; + std::shared_ptr imageJpeg_ = nullptr; + std::shared_ptr imageProcessor_ = nullptr; + VideoParam configParam_; + int32_t frameCount_ = 0; + time_t sendFullTime_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/common/decision_center/src/screen_decision_center.cpp b/services/common/decision_center/src/screen_decision_center.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fb9de49131e00d538f2785623ce0b80d3a26e83a --- /dev/null +++ b/services/common/decision_center/src/screen_decision_center.cpp @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2023 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "screen_decision_center.h" + +#include "dscreen_constants.h" +#include "dscreen_errcode.h" +#include "dscreen_log.h" + +namespace OHOS { +namespace DistributedHardware { +bool ScreenDecisionCenter::IsDirtyRectValid(const std::vector &damages) +{ + DHLOGI("%s: IsDirtyRectValid.", LOG_TAG); + if (damages.empty()) { + DHLOGE("%s: damages size is empty.", LOG_TAG); + return false; + } + int32_t screenWidth = configParam_.GetScreenWidth(); + int32_t screenHeight = configParam_.GetScreenHeight(); + for (const auto &damage : damages) { + if (damage.x < 0 || damage.x > screenWidth || damage.y < 0 || + damage.y > screenHeight || damage.x % TWO == 1 || damage.w % TWO == 1) { + DHLOGE("%s: dirty x:%" PRId32 ", y:%" PRId32 ", w:%" PRId32 ", h:%" PRId32, + LOG_TAG, damage.x, damage.y, damage.w, damage.h); + return false; + } + int32_t width = screenWidth - damage.x; + int32_t height = screenHeight - damage.y; + if (damage.w < 0 || damage.w > width || damage.h < 0 || damage.h > height) { + DHLOGE("%s: dirty x:%" PRId32 ", y:%" PRId32 ", w:%" PRId32 ", h:%" PRId32, + LOG_TAG, damage.x, damage.y, damage.w, damage.h); + return false; + } + } + return true; +} + +bool ScreenDecisionCenter::JudgeDirtyThreshold(const std::vector &damages) +{ + DHLOGI("%s: JudgeDirtyThreshold.", LOG_TAG); + int32_t allDirtyArea = 0; + for (const auto &damage : damages) { + allDirtyArea += damage.w * damage.h; + if (allDirtyArea > DIRTY_REGION_ARE_THRESHOLD) { + DHLOGE("%s: dirtyArea is %." PRId32, LOG_TAG, allDirtyArea); + return false; + } + } + return true; +} + +bool ScreenDecisionCenter::LimitTime(uint32_t timethreshold) +{ + return difftime(time(nullptr), sendFullTime_) >= timethreshold; +} + +int32_t ScreenDecisionCenter::InputBufferImage(sptr &surfaceBuffer, + const std::vector &damages) +{ + DHLOGI("%s: InputBufferImage.", LOG_TAG); + if (surfaceBuffer == nullptr) { + DHLOGE("%s: surfaceBuffer is null.", LOG_TAG); + return ERR_DH_SCREEN_SURFACE_BUFFER_INVALIED; + } + if (damages.empty() || frameCount_ < MIN_SURPPORT_FRAME_COUNT || + LimitTime(FORCE_FULL_IMAGE_TIME_INTERAL) || + !IsDirtyRectValid(damages) || !JudgeDirtyThreshold(damages)) { + DHLOGI("%s: send full image data.", LOG_TAG); + sendFullTime_ = time(nullptr); + int32_t ret = imageProcessor_->ProcessFullImage(surfaceBuffer); + if (ret != DH_SUCCESS) { + DHLOGE("%s: send full data failed.", LOG_TAG); + return ret; + } + } else { + DHLOGI("%s: send dirty data.", LOG_TAG); + int32_t ret = imageJpeg_->ProcessDamageSurface(surfaceBuffer, damages); + if (ret != DH_SUCCESS) { + DHLOGE("%s: send dirty data failed.", LOG_TAG); + return ret; + } + } + frameCount_++; + return DH_SUCCESS; +} + +int32_t ScreenDecisionCenter::ConfigureDecisionCenter(std::shared_ptr &listener, + std::shared_ptr &imageProcessor) +{ + DHLOGI("%s: ConfigureDecisionCenter.", LOG_TAG); + if (listener == nullptr || imageProcessor == nullptr) { + DHLOGE("%s: Image source process is null.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + imageJpeg_ = std::make_shared(configParam_); + imageJpeg_->SetImageProcessListener(listener); + imageProcessor_ = imageProcessor; + return DH_SUCCESS; +} + +int32_t ScreenDecisionCenter::SetJpegSurface(sptr &surface) +{ + DHLOGI("%s: SetJpegSurface.", LOG_TAG); + if (surface ==nullptr) { + DHLOGE("%s: Jpeg source is null.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + return imageJpeg_->SetOutputSurface(surface); +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/common/imageJpeg/include/jpeg_image_processor.h b/services/common/imageJpeg/include/jpeg_image_processor.h new file mode 100644 index 0000000000000000000000000000000000000000..f814fd8d9dd596e5e92b45528bb43ece1ac6a38c --- /dev/null +++ b/services/common/imageJpeg/include/jpeg_image_processor.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2023 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_JPEG_IMAGE_PROCESS_H +#define OHOS_JPEG_IMAGE_PROCESS_H + +#include +#include +#include + +#include "data_buffer.h" +#include "dscreen_constants.h" +#include "iimage_source_processor_listener.h" + +#include "surface.h" +#include "video_param.h" +namespace OHOS { +namespace DistributedHardware { +class JpegImageProcessor : public std::enable_shared_from_this { +public: + explicit JpegImageProcessor(const VideoParam &configParam) : configParam_(configParam){}; + ~JpegImageProcessor() = default; + int32_t SetOutputSurface(sptr surface); + int32_t FillDirtyImages2Surface(const std::shared_ptr &data, uint8_t *lastFrame); + int32_t ProcessDamageSurface(sptr &surfaceBuffer, const std::vector &damages); + int32_t SetImageProcessListener(std::shared_ptr &listener); + void EncodeDamageData(sptr &surfaceBuffer, const OHOS::Rect &damage, + std::shared_ptr &data); + int32_t DecodeDamageData(const std::shared_ptr &data, uint8_t *lastFrame); + int32_t ReplaceDamage2LastFrame(uint8_t *lastFrame, uint8_t *dirtyImageData, const DirtyRect rect); +private: + uint32_t CompressRgbaToJpeg(const OHOS::Rect &damage, uint8_t *inputData, std::shared_ptr &data); + void DecompressJpegToNV12(size_t jpegSize, uint8_t *inputData, uint8_t *outputData); + + static const constexpr char *LOG_TAG = "JpegImageProcessor"; + sptr imageSurface_; + VideoParam configParam_; + std::weak_ptr imageProcessorListener_; + std::mutex dataMutex_; + std::condition_variable dataCond_; +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif \ No newline at end of file diff --git a/services/common/imageJpeg/src/jpeg_image_processor.cpp b/services/common/imageJpeg/src/jpeg_image_processor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5fa6337c30a11f92d22360fe154a896a627f5f40 --- /dev/null +++ b/services/common/imageJpeg/src/jpeg_image_processor.cpp @@ -0,0 +1,316 @@ +/* + * Copyright (c) 2023 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "jpeg_image_processor.h" + +#include +#include +#include +#include "jpeglib.h" +#include +#include + +#ifdef LIBYUV +#include +#endif + +#include "dscreen_errcode.h" +#include "dscreen_log.h" + +namespace OHOS { +namespace DistributedHardware { +int32_t JpegImageProcessor::SetOutputSurface(sptr surface) +{ + DHLOGI("%s: SetOutputSurface.", LOG_TAG); + if (surface == nullptr) { + DHLOGE("%s: SetOutputSurface surface is nullptr.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + imageSurface_ = surface; + return DH_SUCCESS; +} + +int32_t JpegImageProcessor::FillDirtyImages2Surface(const std::shared_ptr &data, uint8_t *lastFrame) +{ + DHLOGI("%s: FillDirtyImages2Surface.", LOG_TAG); + if (imageSurface_ == nullptr) { + DHLOGE("%s: imageSurface_ is nullptr.", LOG_TAG); + return ERR_DH_SCREEN_SURFACE_INVALIED; + } + int32_t lastFrameSize = configParam_.GetScreenWidth() * configParam_.GetScreenHeight() * RGB_CHROMA / TWO; + int32_t ret = DecodeDamageData(data, lastFrame); + if (ret != DH_SUCCESS) { + DHLOGE("%s: Merge dirty failed, ret: %." PRId32, LOG_TAG, ret); + return ret; + } + sptr windowSurfaceBuffer = nullptr; + int32_t releaseFence = -1; + OHOS::BufferRequestConfig requestConfig = { + .width = configParam_.GetScreenWidth(), + .height = configParam_.GetScreenHeight(), + .strideAlignment = STRIDE_ALIGNMENT, + .format = PIXEL_FMT_YCBCR_420_SP, + .usage = HBM_USE_CPU_READ | HBM_USE_CPU_WRITE | HBM_USE_MEM_DMA, + }; + SurfaceError surfaceErr = imageSurface_->RequestBuffer(windowSurfaceBuffer, releaseFence, requestConfig); + if (surfaceErr != SURFACE_ERROR_OK || windowSurfaceBuffer == nullptr) { + DHLOGE("%s: imageSurface request buffer failed, surfaceErr: %." PRId32, LOG_TAG, surfaceErr); + imageSurface_->CancelBuffer(windowSurfaceBuffer); + return surfaceErr; + } + int32_t surfaceBuffeSize = windowSurfaceBuffer->GetSize(); + auto windowSurfaceAddr = static_cast(windowSurfaceBuffer->GetVirAddr()); + ret = memcpy_s(windowSurfaceAddr, surfaceBuffeSize, lastFrame, lastFrameSize); + if (ret != DH_SUCCESS) { + DHLOGE("%s: memcpy lastFrame failed,ret: %." PRId32, LOG_TAG, ret); + imageSurface_->CancelBuffer(windowSurfaceBuffer); + return ret; + } + BufferFlushConfig flushConfig = { {0, 0, windowSurfaceBuffer->GetWidth(), windowSurfaceBuffer-> GetHeight()}, 0}; + surfaceErr = imageSurface_->FlushBuffer(windowSurfaceBuffer, -1, flushConfig); + if (surfaceErr != SURFACE_ERROR_OK) { + DHLOGE("%s: imageSurface flush buffer failed, surfaceErr: %." PRId32, LOG_TAG, surfaceErr); + imageSurface_->CancelBuffer(windowSurfaceBuffer); + return surfaceErr; + } + DHLOGI("%s: FillDirtyImages2Surface success.", LOG_TAG); + return DH_SUCCESS; +} + +int32_t JpegImageProcessor::ProcessDamageSurface(sptr &surfaceBuffer, + const std::vector &damages) +{ + DHLOGI("%s: ProcessDamageSurface.", LOG_TAG); + std::shared_ptr dataBuf = std::make_shared(configParam_.GetScreenWidth() * + configParam_.GetScreenHeight() * RGBA_CHROMA); + dataBuf->SetSize(0); + for (auto item : damages) { + EncodeDamageData(surfaceBuffer, item, dataBuf); + } + std::shared_ptr listener = imageProcessorListener_.lock(); + if (listener == nullptr) { + DHLOGE("%s: Processor listener is null.", LOG_TAG); + imageSurface_->ReleaseBuffer(surfaceBuffer, -1); + return ERR_DH_SCREEN_CODEC_SURFACE_ERROR; + } + dataBuf->SetDataType(VIDEO_PART_SCREEN_DATA); + listener->OnImageProcessDone(dataBuf); + return DH_SUCCESS; +} + +int32_t JpegImageProcessor::SetImageProcessListener(std::shared_ptr &listener) +{ + DHLOGI("%s: SetImageProcessorListener.", LOG_TAG); + imageProcessorListener_ = listener; + return DH_SUCCESS; +} + +void JpegImageProcessor::EncodeDamageData(sptr &surfaceBuffer, + const OHOS::Rect &damage, std::shared_ptr &data) +{ + DHLOGI("%s: EncodeDamageData.", LOG_TAG); + int32_t partialSize = damage.w * damage.h *RGBA_CHROMA; + unsigned char *partialBuffer = new unsigned char[partialSize]; + unsigned char *partialBufferIdx = partialBuffer; + auto surfaceAddrIdx = static_cast(surfaceBuffer->GetVirAddr()); + surfaceAddrIdx += damage.y * configParam_.GetScreenWidth() * RGBA_CHROMA + damage.x * RGBA_CHROMA; + for (int32_t row = 0 ; row < damage.h ; row++) { + int32_t ret = memcpy_s(partialBufferIdx, damage.w * RGBA_CHROMA, surfaceAddrIdx, damage.w * RGBA_CHROMA); + if (ret != DH_SUCCESS) { + DHLOGE("%s: get partail data failed.", LOG_TAG); + imageSurface_->ReleaseBuffer(surfaceBuffer, -1); + delete [] partialBuffer; + return; + } + partialBufferIdx += damage.w * RGBA_CHROMA; + surfaceAddrIdx += configParam_.GetScreenWidth() * RGBA_CHROMA; + } + uint32_t jpegSize = CompressRgbaToJpeg(damage, partialBuffer, data); + DHLOGI("CompressRgbaToJpeg end, jpegSize %." PRId32, jpegSize); + delete [] partialBuffer; +} + +int32_t JpegImageProcessor::DecodeDamageData(const std::shared_ptr &data, uint8_t *lastFrame) +{ + DHLOGI("%s: DecodeDamageData.", LOG_TAG); + std::vector dirtyRectVec = data->GetDirtyRectVec(); + int32_t offset = 0; + int32_t screenWidth = configParam_.GetScreenWidth(); + int32_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("%s: Dirty rect invalid.", LOG_TAG); + 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) { + delete [] jpegData; + return ret; + } + offset += item.dirtySize; + uint8_t *dirtyImageData = new uint8_t[item.width * item.height * RGB_CHROMA] {0}; + DHLOGI("%s: DecompressJpegToNV12.", LOG_TAG); + DecompressJpegToNV12(item.dirtySize, jpegData, dirtyImageData); + DHLOGI("%s: DecompressJpegToNV12 success.", LOG_TAG); + ret = ReplaceDamage2LastFrame(lastFrame, dirtyImageData, item); + if (ret != DH_SUCCESS) { + DHLOGE("ReplaceDamage2LastFrame failed, ret: %." PRId32, ret); + delete [] jpegData; + delete [] dirtyImageData; + return ret; + } + delete [] jpegData; + delete [] dirtyImageData; + } + DHLOGI("%s: DecodeDamageData success.", LOG_TAG); + return DH_SUCCESS; +} + +int32_t JpegImageProcessor::ReplaceDamage2LastFrame(uint8_t *lastFrame, uint8_t *dirtyImageData, const DirtyRect rect) +{ + DHLOGI("%s: ReplaceDamage2LastFrame.", LOG_TAG); + uint8_t *lastFrameIdx = lastFrame; + uint8_t *yData = lastFrameIdx + configParam_.GetScreenWidth() * rect.yPos + rect.xPos; + uint8_t *uData = lastFrameIdx + configParam_.GetScreenWidth() * configParam_.GetScreenHeight() + + 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 + i * configParam_.GetScreenWidth(); + int32_t ret = memcpy_s(yTempData, rect.width, yDirtyData, rect.width); + if (ret != EOK) { + DHLOGE("%s: memcpy yData failed.", LOG_TAG); + return ret; + } + yDirtyData += rect.width; + if (i % TWO) { + uTempData = uData + configParam_.GetScreenWidth() * (i / TWO); + ret = memcpy_s(uTempData, rect.width, uDirtyData, rect.width); + if (ret != EOK) { + DHLOGE("%s: memcpy uData failed.", LOG_TAG); + return ret; + } + uDirtyData += rect.width; + } + } + DHLOGI("%s: ReplaceDamage2LastFrame success.", LOG_TAG); + return DH_SUCCESS; +} + +uint32_t JpegImageProcessor::CompressRgbaToJpeg(const OHOS::Rect &damage, + uint8_t *inputData, std::shared_ptr &data) +{ + DHLOGI("%s: CompressRgbaToJpeg.", LOG_TAG); + jpeg_compress_struct cinfo; + jpeg_error_mgr jerr; + JSAMPROW row_pointer[1]; + cinfo.err = jpeg_std_error(&jerr); + jpeg_create_compress(&cinfo); + unsigned char *outBuffer = nullptr; + unsigned long outSize = 0; + jpeg_mem_dest(&cinfo, &outBuffer, &outSize); + cinfo.image_width = damage.w; + cinfo.image_height = damage.h; + cinfo.input_components = RGB_CHROMA; + cinfo.in_color_space = JCS_RGB; + jpeg_set_defaults(&cinfo); + jpeg_set_quality(&cinfo, JPEG_QUALITY, TRUE); + jpeg_start_compress(&cinfo, TRUE); + unsigned char rgb_buffer[damage.w * RGB_CHROMA]; + unsigned char *pB = inputData; + unsigned char *pG = inputData + 1; + unsigned char *pR = inputData + TWO; + while (cinfo.next_scanline < cinfo.image_height) { + int index = 0; + for (int i = 0 ; i < damage.w ; i++) { + rgb_buffer[index++] = *pB; + rgb_buffer[index++] = *pG; + rgb_buffer[index++] = *pR; + pB += RGBA_CHROMA; + pG += RGBA_CHROMA; + pR += RGBA_CHROMA; + } + row_pointer[0] = rgb_buffer; + (void)jpeg_write_scanlines(&cinfo, row_pointer, 1); + } + jpeg_finish_compress(&cinfo); + DirtyRect rect = {damage.x, damage.y, damage.w, damage.h, outSize}; + data->AddData(static_cast(outSize), outBuffer); + data->AddDirtyRect(rect); + jpeg_destroy_compress(&cinfo); + if (outBuffer != NULL) { + free(outBuffer); + outBuffer = NULL; + } + return (uint32_t)outSize; +} + +void JpegImageProcessor::DecompressJpegToNV12(size_t jpegSize, uint8_t *inputData, uint8_t *outputData) +{ + jpeg_decompress_struct cinfo; + jpeg_error_mgr jerr; + cinfo.err = jpeg_std_error(&jerr); + jpeg_create_decompress(&cinfo); + jpeg_mem_src(&cinfo, inputData, jpegSize); + (void)jpeg_read_header(&cinfo, TRUE); + (void)jpeg_start_decompress(&cinfo); + int32_t row_stride = cinfo.output_width * cinfo.output_components; + JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, row_stride, 1); + int32_t uvIndex = cinfo.output_width * cinfo.output_height; + int32_t i = 0; +#ifdef LIBYUV + uint8_t *rgb = new uint8_t[cinfo.output_width * cinfo.output_height * RGBA_CHROMA]; + int32_t rgbIndex = 0; +#else + int32_t yIndex = 0; +#endif + while (cinfo.output_scanline < cinfo.output_height) { + (void)jpeg_read_scanlines(&cinfo, buffer, 1); + for (int j = 0 ; j < cinfo.output_width ; j++) { +#ifdef LIBYUV + rgb[rgbIndex++] = buffer[0][j * RGB_CHROMA + TWO]; + rgb[rgbIndex++] = buffer[0][j * RGB_CHROMA + 1]; + rgb[rgbIndex++] = buffer[0][j * RGB_CHROMA]; + rgb[rgbIndex++] = 0xff; +#else + int32_t y = ((YR_PARAM * buffer[0][j * RGB_CHROMA] + YG_PARAM * buffer[0][j * RGB_CHROMA + 1] + + YB_PARAM * buffer[0][j * RGB_CHROMA + TWO] + UA_PARAM) >> MOVEBITS) + YA_PARAM; + int32_t u = ((UR_PARAM * buffer[0][j * RGB_CHROMA] - UG_PARAM * buffer[0][j * RGB_CHROMA + 1] + + UB_PARAM * buffer[0][j * RGB_CHROMA + TWO] + UA_PARAM) >> MOVEBITS) + UA_PARAM; + 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)) { + 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); + } +#endif + } + ++i; + } + (void)jpeg_finish_decompress(&cinfo); + jpeg_destroy_decompress(&cinfo); +#ifdef LIBYUV + libyuv::ARGBToNV12(rgb, cinfo.output_width * RGBA_CHROMA, outputData, cinfo.output_width, + outputData + uvIndex, cinfo.output_width, cinfo.output_width, cinfo.output_height); + delete [] rgb; +#endif +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/common/screen_channel/include/iscreen_channel.h b/services/common/screen_channel/include/iscreen_channel.h index b5b06ed85db6e841057baac7dd69b150be1d19ae..0e5a0b649ced1aeabb8b27f01a02abcafd29385a 100644 --- a/services/common/screen_channel/include/iscreen_channel.h +++ b/services/common/screen_channel/include/iscreen_channel.h @@ -26,12 +26,12 @@ namespace DistributedHardware { class IScreenChannel { public: virtual ~IScreenChannel() = default; - virtual int32_t CreateSession(const std::shared_ptr &listener) = 0; virtual int32_t ReleaseSession() = 0; virtual int32_t OpenSession() = 0; virtual int32_t CloseSession() = 0; virtual int32_t SendData(const std::shared_ptr &data) = 0; + virtual void SetJpegSessionFlag(bool flag) = 0; }; } // namespace DistributedHardware } // namespace OHOS diff --git a/services/screenclient/BUILD.gn b/services/screenclient/BUILD.gn index 380caa653e87ee5ead567957e7135623c649d914..1e92ec4f43e6ed9c428ff6a40b368aec0496eaf5 100644 --- a/services/screenclient/BUILD.gn +++ b/services/screenclient/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2022 Huawei Device Co., Ltd. +# Copyright (c) 2022-2023 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 @@ -19,7 +19,7 @@ import( ohos_shared_library("distributed_screen_client") { include_dirs = [ "${windowmanager_path}/interfaces/innerkits/wm", - "${graphicstandard_path}/interfaces/innerkits/surface", + "${graphicstandard_path}/interfaces/inner_api/surface", "${graphicstandard_path}/rosen/modules/render_service_client/core/ui", "${fwk_common_path}/utils/include", "//foundation/multimodalinput/input/interfaces/native/innerkits/event/include/", @@ -47,7 +47,10 @@ ohos_shared_library("distributed_screen_client") { "LOG_DOMAIN=0xD004100", ] - external_deps = [ "input:libmmi-client" ] + external_deps = [ + "graphic_standard:libgraphic_utils", + "input:libmmi-client", + ] part_name = "distributed_screen" subsystem_name = "distributedhardware" diff --git a/services/screenclient/include/screen_client_window_adapter.h b/services/screenclient/include/screen_client_window_adapter.h index 9b8d2300cbe6a6eb1dd6bd848b973d577c0501d9..3cef7730b4f118954e09e892d5b0e116d7eb6866 100644 --- a/services/screenclient/include/screen_client_window_adapter.h +++ b/services/screenclient/include/screen_client_window_adapter.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-2023 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 @@ -48,6 +48,7 @@ private: ~ScreenClientWindowAdapter() = default; std::map> windowIdMap_; std::mutex windowIdMapMutex_; + sptr surface_ = nullptr; }; class ScreenClientInputEventListener : public Rosen::IInputEventConsumer { diff --git a/services/screenclient/src/screen_client_window_adapter.cpp b/services/screenclient/src/screen_client_window_adapter.cpp index a00da85a1675ae9f6163b51c2e1daeff7374caf7..c03ad6776486fa6e2e062b1fbb9df28e11a3726b 100644 --- a/services/screenclient/src/screen_client_window_adapter.cpp +++ b/services/screenclient/src/screen_client_window_adapter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-2023 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 @@ -55,6 +55,7 @@ sptr ScreenClientWindowAdapter::CreateWindow(std::shared_ptrFlushImplicitTransaction(); std::shared_ptr listener = std::make_shared(ScreenClientInputEventListener()); diff --git a/services/screenservice/sinkservice/screenregionmgr/include/screenregion.h b/services/screenservice/sinkservice/screenregionmgr/include/screenregion.h index bab1ee68a32a4ee67a6cfe9e81a343e75c6a4122..120044d2daeba4512f7661029b9f613c11b4468f 100644 --- a/services/screenservice/sinkservice/screenregionmgr/include/screenregion.h +++ b/services/screenservice/sinkservice/screenregionmgr/include/screenregion.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-2023 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 @@ -55,12 +55,15 @@ public: int32_t Start(); int32_t Stop(); std::shared_ptr GetWindowProperty(); + void SetScreenVersion(std::string version); + std::string GetScreenVersion(); private: std::string remoteDevId_; uint64_t screenId_; // local screen id uint64_t displayId_; // local display id bool isRunning = false; + std::string version_ = "1.0"; std::shared_ptr videoParam_ = nullptr; std::shared_ptr mapRelation_ = nullptr; diff --git a/services/screenservice/sinkservice/screenregionmgr/include/screenregionmgr.h b/services/screenservice/sinkservice/screenregionmgr/include/screenregionmgr.h index 0622e23f75df8d81402ebf858ee2a230587c0d11..34256b7422024847ffc9deccbf0796cbb8d6481c 100644 --- a/services/screenservice/sinkservice/screenregionmgr/include/screenregionmgr.h +++ b/services/screenservice/sinkservice/screenregionmgr/include/screenregionmgr.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-2023 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 @@ -42,6 +42,7 @@ private: std::map> screenRegions_; std::mutex screenRegionsMtx_; std::string localDevId_; + std::string version_ = "1.0"; sptr GetDScreenSourceSA(const std::string &devId); int32_t NotifyRemoteScreenService(const std::string &remoteDevId, const std::string &dhId, diff --git a/services/screenservice/sinkservice/screenregionmgr/src/screenregion.cpp b/services/screenservice/sinkservice/screenregionmgr/src/screenregion.cpp index 27fd2e0e5af2f639b51aed463792fbfd39d1156d..6e8fafd9b37129eb3e58dbeaf2eb8766a6e950f6 100644 --- a/services/screenservice/sinkservice/screenregionmgr/src/screenregion.cpp +++ b/services/screenservice/sinkservice/screenregionmgr/src/screenregion.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-2023 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 @@ -129,6 +129,15 @@ int32_t ScreenRegion::SetUpWindow() return DH_SUCCESS; } +void ScreenRegion::SetScreenVersion(std::string version) +{ + version_ = version; +} + +std::string ScreenRegion::GetScreenVersion() +{ + return version_; +} int32_t ScreenRegion::SetUp() { @@ -142,7 +151,7 @@ int32_t ScreenRegion::SetUp() if (sinkTrans_ == nullptr) { sinkTrans_ = std::make_shared(); } - + sinkTrans_->SetScreenVersion(version_); sinkTrans_->RegisterStateCallback(shared_from_this()); sinkTrans_->SetImageSurface(surface_); ret = sinkTrans_->SetUp(*videoParam_, *videoParam_, remoteDevId_); diff --git a/services/screenservice/sinkservice/screenregionmgr/src/screenregionmgr.cpp b/services/screenservice/sinkservice/screenregionmgr/src/screenregionmgr.cpp index 4be61d56636f1036dca1a2260e10a88dc27070f8..15802569fa2793a1ce22b332b4457fb9416ed545 100644 --- a/services/screenservice/sinkservice/screenregionmgr/src/screenregionmgr.cpp +++ b/services/screenservice/sinkservice/screenregionmgr/src/screenregionmgr.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-2023 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 @@ -121,6 +121,9 @@ bool ScreenRegionManager::CheckContentJson(json &eventContentJson) if (!IsString(eventContentJson, KEY_DH_ID)) { return false; } + if (eventContentJson.contains(KEY_VERSION) && !IsString(eventContentJson, KEY_VERSION)) { + return false; + } return true; } @@ -138,7 +141,9 @@ void ScreenRegionManager::HandleNotifySetUp(const std::string &remoteDevId, cons NotifyRemoteSourceSetUpResult(remoteDevId, "", ERR_DH_SCREEN_SA_SCREENREGION_SETUP_FAIL, ""); return; } - + if (eventContentJson.contains(KEY_VERSION)) { + version_ = eventContentJson[KEY_VERSION].get(); + } uint64_t screenId = eventContentJson[KEY_SCREEN_ID].get(); std::string dhId = eventContentJson[KEY_DH_ID].get(); @@ -167,7 +172,7 @@ void ScreenRegionManager::HandleNotifySetUp(const std::string &remoteDevId, cons } screenRegions_[remoteDevId] = screenRegion; } - + screenRegion->SetScreenVersion(version_); ret = screenRegion->SetUp(); if (ret != DH_SUCCESS) { DHLOGE("screen region setup failed"); diff --git a/services/screenservice/sourceservice/BUILD.gn b/services/screenservice/sourceservice/BUILD.gn index a9cb9d7e74631e5bbcf7d6637c8f4ee07cbd4bd5..6d68fc6bffc016f23da58007ad54567a3017cfe8 100644 --- a/services/screenservice/sourceservice/BUILD.gn +++ b/services/screenservice/sourceservice/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2022 Huawei Device Co., Ltd. +# Copyright (c) 2022-2023 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 @@ -19,14 +19,14 @@ import( ohos_shared_library("distributed_screen_source") { include_dirs = [ "//base/hiviewdfx/hisysevent/interfaces/native/innerkits/hisysevent/include", - "//third_party/json/include", - "${windowmanager_path}/interfaces/innerkits/dm", "//commonlibrary/c_utils/base/include", - "//utils/system/safwk/native/include", "//foundation/graphic/graphic_2d/interfaces/innerkits/surface", + "//third_party/json/include", + "//third_party/libjpeg-turbo", + "${distributedhardwarefwk_path}/interfaces/inner_kits/include", + "${windowmanager_path}/interfaces/innerkits/dm", "${fwk_common_path}/utils/include", "${mediastandard_path}/interfaces/inner_api/native", - "${distributedhardwarefwk_path}/interfaces/inner_kits/include", ] include_dirs += [ @@ -44,10 +44,8 @@ ohos_shared_library("distributed_screen_source") { "${services_path}/screentransport/screensourceprocessor/include", "${services_path}/screentransport/screensourceprocessor/encoder/include", "${services_path}/screentransport/screensourcetrans/include", - "//drivers/peripheral/display/interfaces/include", - "//drivers/peripheral/base", - "//foundation/graphic/graphic_2d/rosen/modules/render_service_base/include", - "//foundation/graphic/graphic_2d/utils/buffer_handle/export", + "${services_path}/common/imageJpeg/include", + "${services_path}/common/decision_center/include", ] sources = [ @@ -67,6 +65,7 @@ ohos_shared_library("distributed_screen_source") { deps = [ "${common_path}:distributed_screen_utils", "${distributedhardwarefwk_path}/interfaces/inner_kits:libdhfwk_sdk", + "${mediastandard_path}/interfaces/inner_api/native:media_client", "${services_path}/screentransport/screensourcetrans:distributed_screen_sourcetrans", "${windowmanager_path}/dm:libdm", ] @@ -79,6 +78,8 @@ ohos_shared_library("distributed_screen_source") { external_deps = [ "c_utils:utils", + "drivers_peripheral_display:hdi_display_device", + "graphic_standard:libcomposer", "graphic_standard:surface", "ipc:ipc_core", "multimedia_image_framework:image_native", diff --git a/services/screenservice/sourceservice/dscreenmgr/include/dscreen.h b/services/screenservice/sourceservice/dscreenmgr/include/dscreen.h index 76f0b3b8a03cbe64d0b70c40aa92f2bab35f9283..2fb81b3a73c216ed8ead1c54a9c144cfd144fa8a 100644 --- a/services/screenservice/sourceservice/dscreenmgr/include/dscreen.h +++ b/services/screenservice/sourceservice/dscreenmgr/include/dscreen.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-2023 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 @@ -89,6 +89,8 @@ public: std::string GetDHId() const; std::string GetDevId() const; int32_t AddTask(const std::shared_ptr &task); + void SetScreenVersion(std::string &version); + std::string GetScreenVersion(); private: void TaskThreadLoop(); @@ -117,6 +119,7 @@ private: std::mutex taskQueueMtx_; std::queue> taskQueue_; bool taskThreadRunning_; + std::string version_ = "1.0"; }; } // namespace DistributedHardware } // namespace OHOS diff --git a/services/screenservice/sourceservice/dscreenmgr/include/dscreen_manager.h b/services/screenservice/sourceservice/dscreenmgr/include/dscreen_manager.h index 72aba53b8593c2cc57e3464cc3f05887976c96e6..c970b29f7e4480a9962dfabef15d4f3287cf150c 100644 --- a/services/screenservice/sourceservice/dscreenmgr/include/dscreen_manager.h +++ b/services/screenservice/sourceservice/dscreenmgr/include/dscreen_manager.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-2023 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 @@ -63,6 +63,8 @@ public: int32_t RemoveFromGroup(const std::shared_ptr &changedScreen, uint64_t screenId); void GetScreenDumpInfo(std::string &result); void PublishMessage(const DHTopic topic, const std::shared_ptr &dScreen); + void SetScreenVersion(std::string &version); + std::string GetScreenVersion(); private: ~DScreenManager(); DScreenManager(); @@ -74,6 +76,7 @@ private: sptr dScreenGroupListener_ = nullptr; std::shared_ptr dScreenCallback_ = nullptr; std::string localDevId_; + std::string version_ = "1.0"; sptr GetDScreenSinkSA(const std::string &devId); int32_t NotifyRemoteScreenService(const std::string &devId, int32_t eventCode, const std::string &eventContent); diff --git a/services/screenservice/sourceservice/dscreenmgr/src/dscreen.cpp b/services/screenservice/sourceservice/dscreenmgr/src/dscreen.cpp index bbf6c0155142921c692d3899bb673a865d2e8ddf..b7a4e704a959bd7b0c8c59fef54da77dddda4634 100644 --- a/services/screenservice/sourceservice/dscreenmgr/src/dscreen.cpp +++ b/services/screenservice/sourceservice/dscreenmgr/src/dscreen.cpp @@ -106,6 +106,15 @@ uint64_t DScreen::GetScreenId() const return screenId_; } +void DScreen::SetScreenVersion(std::string &version) +{ + version_ = version; +} +std::string DScreen::GetScreenVersion() +{ + return version_; +} + std::string DScreen::GetDHId() const { return dhId_; @@ -392,21 +401,13 @@ int32_t DScreen::SetUp() if (sourceTrans_ == nullptr) { sourceTrans_ = std::make_shared(); } - + sourceTrans_->SetScreenVersion(version_); sourceTrans_->RegisterStateCallback(shared_from_this()); int32_t ret = sourceTrans_->SetUp(*videoParam_, *videoParam_, devId_); if (ret != DH_SUCCESS) { DHLOGE("source trans SetUp failed."); return ret; } - - sptr windowSurface = sourceTrans_->GetImageSurface(); - if (windowSurface == nullptr) { - DHLOGE("DScreen SetUp failed."); - return ERR_DH_SCREEN_SA_DSCREEN_SETUP_FAILED; - } - - ScreenMgrAdapter::GetInstance().SetImageSurface(screenId_, windowSurface); DHLOGI("DScreen SetUp success."); return DH_SUCCESS; } @@ -419,12 +420,17 @@ int32_t DScreen::Start() DHLOGE("source trans not init."); return ERR_DH_SCREEN_SA_SOURCETRANS_NOT_INIT; } - int32_t ret = sourceTrans_->Start(); if (ret != DH_SUCCESS) { DHLOGE("source trans start failed."); return ret; } + sptr windowSurface = sourceTrans_->GetImageSurface(); + if (windowSurface == nullptr) { + DHLOGE("DScreen SetUp failed."); + return ERR_DH_SCREEN_SA_DSCREEN_SETUP_FAILED; + } + ScreenMgrAdapter::GetInstance().SetImageSurface(screenId_, windowSurface); return DH_SUCCESS; } diff --git a/services/screenservice/sourceservice/dscreenmgr/src/dscreen_manager.cpp b/services/screenservice/sourceservice/dscreenmgr/src/dscreen_manager.cpp index 35cdb154e93ec36dc51ce4a3ddaf1412556a8020..ad3191f350557d0a3c7e7c38d3128536efe7ee2e 100644 --- a/services/screenservice/sourceservice/dscreenmgr/src/dscreen_manager.cpp +++ b/services/screenservice/sourceservice/dscreenmgr/src/dscreen_manager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-2023 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 @@ -268,7 +268,7 @@ int32_t DScreenManager::EnableDistributedScreen(const std::string &devId, const DHLOGI("dScreen state Already is ENABLED or ENABLING."); return DH_SUCCESS; } - + dScreen ->SetScreenVersion(version_); dScreens_[dScreenIdx] = dScreen; int32_t ret = dScreen->AddTask(std::make_shared(TaskType::TASK_ENABLE, reqId, attrs)); if (ret != DH_SUCCESS) { @@ -484,7 +484,7 @@ void DScreenManager::NotifyRemoteSinkSetUp(const std::shared_ptr &dScre return; } eventContentJson[KEY_VIDEO_PARAM] = *(dScreen->GetVideoParam()); - + eventContentJson[KEY_VERSION] = dScreen->GetScreenVersion(); if (mapRelations_.count(dScreen->GetScreenId()) == 0) { DHLOGE("mapRelation not found, back to enabled state screedId: %ulld", dScreen->GetScreenId()); dScreen->SetState(ENABLED); @@ -545,5 +545,15 @@ void DScreenManager::HandleNotifySetUpResult(const std::string &remoteDevId, con dScreens_[dScreenIdx]->AddTask(std::make_shared(TaskType::TASK_CONNECT, "")); } + +void DScreenManager::SetScreenVersion(std::string &version) +{ + version_ = version; +} + +std::string DScreenManager::GetScreenVersion() +{ + return version_; +} } // namespace DistributedHardware } // namespace OHOS \ No newline at end of file diff --git a/services/screenservice/sourceservice/dscreenservice/src/dscreen_source_service.cpp b/services/screenservice/sourceservice/dscreenservice/src/dscreen_source_service.cpp index 0ff9d570cbe96d626b6695fe9c5ec5f4ef7ef1bb..89d4d6376396e1037aedac1f6cb978a85260daaf 100644 --- a/services/screenservice/sourceservice/dscreenservice/src/dscreen_source_service.cpp +++ b/services/screenservice/sourceservice/dscreenservice/src/dscreen_source_service.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-2023 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 @@ -112,6 +112,8 @@ int32_t DScreenSourceService::RegisterDistributedHardware(const std::string &dev const EnableParam ¶m, const std::string &reqId) { std::string attrs = param.attrs; + std::string version = param.version; + DScreenManager::GetInstance().SetScreenVersion(version); int ret = DScreenManager::GetInstance().EnableDistributedScreen(devId, dhId, attrs, reqId); if (ret != DH_SUCCESS) { DHLOGE("enable distributedScreen failed. devId: %s, dhId: %s, reqId: %s, attrs: %s", diff --git a/services/screenservice/test/unittest/sourceservice/dscreenmgr/BUILD.gn b/services/screenservice/test/unittest/sourceservice/dscreenmgr/BUILD.gn index 66a4d032e673f2c37db4df9dde68092038566ddc..19a3bcf88525162590142ae6b376c486b13a2e10 100644 --- a/services/screenservice/test/unittest/sourceservice/dscreenmgr/BUILD.gn +++ b/services/screenservice/test/unittest/sourceservice/dscreenmgr/BUILD.gn @@ -35,6 +35,7 @@ config("module_private_config") { include_dirs += [ "./include", + "${services_path}/common/decision_center/include", "${services_path}/screenservice/sourceservice/dscreenmgr/include", "${services_path}/common/utils/include", "${services_path}/common/databuffer/include", @@ -46,6 +47,8 @@ config("module_private_config") { "${distributedscreen_path}/interfaces/innerkits/native_cpp/screen_sink/include/callback", "${distributedscreen_path}/interfaces/innerkits/native_cpp/screen_source/include", "${distributedscreen_path}/interfaces/innerkits/native_cpp/screen_source/include/callback", + "${services_path}/common/imageJpeg/include", + "${services_path}/screentransport/screensourceprocessor/encoder/include", ] } diff --git a/services/screenservice/test/unittest/sourceservice/dscreenmgr/src/dscreen_test.cpp b/services/screenservice/test/unittest/sourceservice/dscreenmgr/src/dscreen_test.cpp index a3226ff80ff42bf73d583c3fbbfe8b345f660917..04d0b554e37a872958d8b4fd8e9627ecc96bab3b 100644 --- a/services/screenservice/test/unittest/sourceservice/dscreenmgr/src/dscreen_test.cpp +++ b/services/screenservice/test/unittest/sourceservice/dscreenmgr/src/dscreen_test.cpp @@ -328,6 +328,7 @@ HWTEST_F(DScreenTest, SetUp_001, TestSize.Level1) dScreen_->videoParam_->SetVideoWidth(100); dScreen_->videoParam_->SetScreenHeight(100); dScreen_->videoParam_->SetScreenWidth(100); + dScreen_->version_ = "1.0"; int32_t ret = dScreen_->SetUp(); EXPECT_EQ(-1, ret); } @@ -348,6 +349,7 @@ HWTEST_F(DScreenTest, SetUp_002, TestSize.Level1) dScreen_->videoParam_->SetVideoWidth(100); dScreen_->videoParam_->SetScreenHeight(100); dScreen_->videoParam_->SetScreenWidth(100); + dScreen_->version_ = "1.0"; int32_t ret = dScreen_->SetUp(); EXPECT_EQ(-1, ret); } diff --git a/services/screentransport/screendatachannel/include/screen_data_channel_impl.h b/services/screentransport/screendatachannel/include/screen_data_channel_impl.h index 7fa6a9ad49300c2ea4da87470f1d0cf0ecf2e541..0b43f3b4ceab1f3b48ae5be30b9074290798b961 100644 --- a/services/screentransport/screendatachannel/include/screen_data_channel_impl.h +++ b/services/screentransport/screendatachannel/include/screen_data_channel_impl.h @@ -31,13 +31,16 @@ class ScreenDataChannelImpl : public IScreenChannel, public: explicit ScreenDataChannelImpl(std::string peerDevId) : peerDevId_(peerDevId) {}; ~ScreenDataChannelImpl() override = default; - int32_t CreateSession(const std::shared_ptr &listener) override; int32_t ReleaseSession() override; int32_t OpenSession() override; int32_t CloseSession() override; int32_t SendData(const std::shared_ptr &screenData) override; - + void SetJpegSessionFlag(bool flag) override; + int32_t SendFullData(const std::shared_ptr &screenData); + int32_t SendDirtyData(const std::shared_ptr &screenData); + void ProcessDirtyData(const StreamData *data, std::shared_ptr dataBuffer, const StreamData *ext); + void ProcessDullData(const StreamData *data, std::shared_ptr dataBuffer); void OnSessionOpened(int32_t sessionId, int32_t result) override; void OnSessionClosed(int32_t sessionId) override; void OnBytesReceived(int32_t sessionId, const void *data, uint32_t dataLen) override; @@ -46,9 +49,12 @@ public: private: static const constexpr char *LOG_TAG = "ScreenDataChannel"; - + bool jpegSessionFlag_ = false; const std::string peerDevId_; int32_t sessionId_ = 0; + int32_t jpegSessionId_ = 0; + bool dataSessionOpened = false; + bool jpegSessionOpened = false; std::weak_ptr channelListener_; }; } // namespace DistributedHardware diff --git a/services/screentransport/screendatachannel/src/screen_data_channel_impl.cpp b/services/screentransport/screendatachannel/src/screen_data_channel_impl.cpp index a303fa1a7a6084ef53a5d0f35629eef856481a86..166b77e400b156d7a90b13efb620ad11d2378999 100644 --- a/services/screentransport/screendatachannel/src/screen_data_channel_impl.cpp +++ b/services/screentransport/screendatachannel/src/screen_data_channel_impl.cpp @@ -22,6 +22,8 @@ #include "dscreen_hisysevent.h" #include "dscreen_log.h" #include "dscreen_util.h" +#include "nlohmann/json.hpp" +#include "dscreen_json_util.h" namespace OHOS { namespace DistributedHardware { @@ -32,42 +34,71 @@ int32_t ScreenDataChannelImpl::CreateSession(const std::shared_ptr softbusListener = shared_from_this(); ret = SoftbusAdapter::GetInstance().RegisterSoftbusListener(softbusListener, DATA_SESSION_NAME, peerDevId_); if (ret != DH_SUCCESS) { - DHLOGE("%s: Register softbus adapter listener failed ret: %" PRId32, LOG_TAG, ret); + DHLOGE("%s: Register data adapter listener failed ret: %" PRId32, LOG_TAG, ret); return ret; } - + if (jpegSessionFlag_ == true) { + ret = + SoftbusAdapter::GetInstance().CreateSoftbusSessionServer(PKG_NAME, JPEG_SESSION_NAME, peerDevId_); + if (ret != DH_SUCCESS) { + DHLOGE("%s: Create jpeg session failed ret: %" PRId32, LOG_TAG, ret); + return ret; + } + std::shared_ptr softbusListener = shared_from_this(); + ret = + SoftbusAdapter::GetInstance().RegisterSoftbusListener(softbusListener, JPEG_SESSION_NAME, peerDevId_); + if (ret != DH_SUCCESS) { + DHLOGE("%s: Register jpeg adapter listener failed ret: %" PRId32, LOG_TAG, ret); + return ret; + } + } channelListener_ = listener; - DHLOGI("%s: Create softbus session success", LOG_TAG); + DHLOGI("%s: Create session success", LOG_TAG); return DH_SUCCESS; } +void ScreenDataChannelImpl::SetJpegSessionFlag(bool flag) +{ + jpegSessionFlag_ = flag; +} + int32_t ScreenDataChannelImpl::ReleaseSession() { DHLOGI("%s: ReleaseSession, peerDevId(%s)", LOG_TAG, GetAnonyString(peerDevId_).c_str()); int32_t ret = SoftbusAdapter::GetInstance().RemoveSoftbusSessionServer(PKG_NAME, DATA_SESSION_NAME, peerDevId_); if (ret != DH_SUCCESS) { - DHLOGE("%s: Release softbus session failed ret: %" PRId32, LOG_TAG, ret); + DHLOGE("%s: Release data session failed ret: %" PRId32, LOG_TAG, ret); return ret; } - ret = SoftbusAdapter::GetInstance().UnRegisterSoftbusListener(DATA_SESSION_NAME, peerDevId_); if (ret != DH_SUCCESS) { - DHLOGE("%s: UnRegister softbus adapter listener failed ret: %" PRId32, LOG_TAG, ret); + DHLOGE("%s: UnRegister data adapter listener failed ret: %" PRId32, LOG_TAG, ret); return ret; } - DHLOGI("%s: Release softbus session success", LOG_TAG); + if (jpegSessionFlag_ == true) { + int32_t ret = SoftbusAdapter::GetInstance().RemoveSoftbusSessionServer(PKG_NAME, JPEG_SESSION_NAME, peerDevId_); + if (ret != DH_SUCCESS) { + DHLOGE("%s: Release jpeg session failed ret: %" PRId32, LOG_TAG, ret); + return ret; + } + ret = SoftbusAdapter::GetInstance().UnRegisterSoftbusListener(JPEG_SESSION_NAME, peerDevId_); + if (ret != DH_SUCCESS) { + DHLOGE("%s: UnRegister jpeg adapter listener failed ret: %" PRId32, LOG_TAG, ret); + return ret; + } + jpegSessionFlag_ = false; + } + DHLOGI("%s: Release session success", LOG_TAG); return DH_SUCCESS; } @@ -77,12 +108,21 @@ int32_t ScreenDataChannelImpl::OpenSession() int32_t sessionId = SoftbusAdapter::GetInstance().OpenSoftbusSession(DATA_SESSION_NAME, DATA_SESSION_NAME, peerDevId_); if (sessionId < 0) { - DHLOGE("%s: Open screen session failed, ret: %" PRId32, LOG_TAG, sessionId); - ReportOptFail(DSCREEN_OPT_FAIL, sessionId, "Open screen session failed"); + DHLOGE("%s: Open data session failed, ret: %" PRId32, LOG_TAG, sessionId); + ReportOptFail(DSCREEN_OPT_FAIL, sessionId, "Open data session failed"); return ERR_DH_SCREEN_TRANS_ERROR; } sessionId_ = sessionId; - + if (jpegSessionFlag_ == true) { + int32_t sessionId = + SoftbusAdapter::GetInstance().OpenSoftbusSession(DATA_SESSION_NAME, JPEG_SESSION_NAME, peerDevId_); + if (sessionId < 0) { + DHLOGE("%s: Open jpeg session failed, ret: %" PRId32, LOG_TAG, sessionId); + ReportOptFail(DSCREEN_OPT_FAIL, sessionId, "Open jpeg session failed"); + return ERR_DH_SCREEN_TRANS_ERROR; + } + jpegSessionId_ = sessionId; + } DHLOGI("%s: Open screen session success, sessionId %" PRId32, LOG_TAG, sessionId_); return DH_SUCCESS; } @@ -94,39 +134,107 @@ int32_t ScreenDataChannelImpl::CloseSession() DHLOGD("%s: Session is not opened.", LOG_TAG); return ERR_DH_SCREEN_TRANS_SESSION_NOT_OPEN; } - int32_t ret = SoftbusAdapter::GetInstance().CloseSoftbusSession(sessionId_); if (ret != DH_SUCCESS) { DHLOGE("%s: Close screen session failed ret: %" PRId32, LOG_TAG, ret); return ret; } sessionId_ = 0; - - DHLOGI("%s: Close screen session success", LOG_TAG); + if (jpegSessionFlag_ == true && jpegSessionId_ != 0) { + int32_t ret = SoftbusAdapter::GetInstance().CloseSoftbusSession(sessionId_); + if (ret != DH_SUCCESS) { + DHLOGE("%s: Close jpeg session failed ret: %" PRId32, LOG_TAG, ret); + return ret; + } + jpegSessionId_ = 0; + } + DHLOGI("%s: Close session success", LOG_TAG); return DH_SUCCESS; } int32_t ScreenDataChannelImpl::SendData(const std::shared_ptr &screenData) { - DHLOGD("%s: SendData, sessionId %" PRId32, LOG_TAG, sessionId_); - if (screenData == nullptr) { + DHLOGI("%s: SendData.", LOG_TAG); + if (screenData == nullptr || screenData->Data() == nullptr) { DHLOGE("%s: Screen data is null", LOG_TAG); return ERR_DH_SCREEN_TRANS_NULL_VALUE; } + uint8_t dataType = screenData->DataType(); + if (dataType == VIDEO_PART_SCREEN_DATA) { + int32_t ret = SendDirtyData(screenData); + if (ret != DH_SUCCESS) { + DHLOGE("%s: send dirty data failed, ret: %." PRId32, LOG_TAG, ret); + return ret; + } + } else if (dataType == VIDEO_FULL_SCREEN_DATA) { + int32_t ret = SendFullData(screenData); + if (ret != DH_SUCCESS) { + DHLOGE("%s: send full data failed, ret: %." PRId32, LOG_TAG, ret); + return ret; + } + } + return DH_SUCCESS; +} +int32_t ScreenDataChannelImpl::SendFullData(const std::shared_ptr &screenData) +{ + DHLOGI("%s: SendFullData sessionId: %." PRId32, LOG_TAG, sessionId_); + if (screenData == nullptr) { + DHLOGE("%s: Screen data is null", LOG_TAG); + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } StreamData data = {reinterpret_cast(screenData->Data()), screenData->Capacity()}; - StreamData ext = {nullptr}; + StreamData ext = {0}; StreamFrameInfo frameInfo = {0}; - int32_t ret = SoftbusAdapter::GetInstance().SendSoftbusStream(sessionId_, &data, &ext, &frameInfo); if (ret != DH_SUCCESS) { - DHLOGE("%s: Send screen data failed ret: %" PRId32, LOG_TAG, ret); + DHLOGE("%s: Send full data failed ret: %" PRId32, LOG_TAG, ret); return ret; } + DHLOGI("%s: SendFullData success.", LOG_TAG); + return DH_SUCCESS; +} +int32_t ScreenDataChannelImpl::SendDirtyData(const std::shared_ptr &screenData) +{ + DHLOGI("%s: SendDirtyData sessionId: %." PRId32, LOG_TAG, jpegSessionId_); + if (screenData == nullptr) { + DHLOGE("%s: Screen data is null", LOG_TAG); + return ERR_DH_SCREEN_TRANS_NULL_VALUE; + } + nlohmann::json rectJson; + std::vector dirtyRectVec = screenData->GetDirtyRectVec(); + rectJson["dataType"] = screenData->DataType(); + rectJson["dirtySize"] = static_cast(dirtyRectVec.size()); + int32_t rectIndex = 0; + for (auto item : dirtyRectVec) { + std::string tempRectIndex = std::to_string(rectIndex); + rectJson[tempRectIndex] = {item.xPos, item.yPos, item.width, item.height, item.dirtySize}; + rectIndex++; + } + StreamData data = {reinterpret_cast(screenData->Data()), screenData->Capacity()}; + std::string rectInfo = rectJson.dump(); + char *dirtyInfo = new char[rectInfo.length() + 1] {0}; + int32_t ret = memcpy_s(dirtyInfo, rectInfo.length(), rectInfo.c_str(), rectInfo.length()); + if (ret != EOK) { + DHLOGE("SendDirtyData memcpy_s failed."); + delete [] dirtyInfo; + return ret; + } + StreamData ext = {dirtyInfo, rectInfo.length() + 1}; + StreamFrameInfo frameInfo = {0}; + ret = SoftbusAdapter::GetInstance().SendSoftbusStream(jpegSessionId_, &data, &ext, &frameInfo); + if (ret != DH_SUCCESS) { + DHLOGE("%s: Send dirty data failed ret: %" PRId32, LOG_TAG, ret); + delete [] dirtyInfo; + return ret; + } + delete [] dirtyInfo; + DHLOGI("%s: SendDirtyData success.", LOG_TAG); return DH_SUCCESS; } + void ScreenDataChannelImpl::OnSessionOpened(int32_t sessionId, int32_t result) { DHLOGI("%s: OnScreenSessionOpened, sessionId: %" PRId32", result: %" PRId32, LOG_TAG, sessionId, result); @@ -134,14 +242,27 @@ void ScreenDataChannelImpl::OnSessionOpened(int32_t sessionId, int32_t result) DHLOGE("Session open failed", LOG_TAG); return; } - + if (jpegSessionFlag_ == false) { + dataSessionOpened = true; + sessionId_ = sessionId; + } else { + if (sessionId == sessionId_) { + dataSessionOpened = true; + sessionId_ = sessionId; + } else if (sessionId == jpegSessionId_) { + jpegSessionOpened = true; + jpegSessionId_ = sessionId; + } + if (!dataSessionOpened || !jpegSessionOpened) { + return; + } + } std::shared_ptr listener = channelListener_.lock(); if (listener == nullptr) { DHLOGE("%s: Channel listener is null", LOG_TAG); return; } listener->OnSessionOpened(); - sessionId_ = sessionId; } void ScreenDataChannelImpl::OnSessionClosed(int32_t sessionId) @@ -164,32 +285,84 @@ void ScreenDataChannelImpl::OnBytesReceived(int32_t sessionId, const void *data, DHLOGD("%s: OnScreenBytesReceived data channel not support yet", LOG_TAG); } -void ScreenDataChannelImpl::OnStreamReceived(int32_t sessionId, const StreamData *data, const StreamData *ext, - const StreamFrameInfo *param) +void ScreenDataChannelImpl::OnStreamReceived(int32_t sessionId, const StreamData *data, + const StreamData *ext, const StreamFrameInfo *param) { - (void)ext; - (void)param; - + DHLOGI("%s: OnStreamReceived, receiv data from softbus.", LOG_TAG); if (data == nullptr) { DHLOGE("%s: Stream data is null", LOG_TAG); return; } + auto dataBuffer = std::make_shared(data->bufLen); + if (ext->bufLen == 0) { + DHLOGI("sink received full data."); + ProcessDullData(data, dataBuffer); + return; + } else { + DHLOGI("sink received dirty data."); + ProcessDirtyData(data, dataBuffer, ext); + } +} +void ScreenDataChannelImpl::ProcessDullData(const StreamData *data, std::shared_ptr dataBuffer) +{ + DHLOGI("%s: ProcessDullData.", LOG_TAG); std::shared_ptr listener = channelListener_.lock(); if (listener == nullptr) { - DHLOGE("%s: Channel listener is null", LOG_TAG); + DHLOGE("%s: Channel listener is null.", LOG_TAG); return; } + int32_t ret = memcpy_s(dataBuffer->Data(), dataBuffer->Capacity(), + reinterpret_cast(data->buf), data->bufLen); + if (ret != EOK) { + DHLOGE("%s: Full data memcpy failed.", LOG_TAG); + return; + } + dataBuffer->SetDataType(VIDEO_FULL_SCREEN_DATA); + listener->OnDataReceived(dataBuffer); +} - DHLOGI("%s: OnScreenStreamReceived, sessionId:%" PRId32", dataSize:%" PRIu32, LOG_TAG, sessionId, data->bufLen); - auto dataBuffer = std::make_shared(data->bufLen); - - int32_t ret = memcpy_s(dataBuffer->Data(), dataBuffer->Capacity(), reinterpret_cast(data->buf), - data->bufLen); +void ScreenDataChannelImpl::ProcessDirtyData(const StreamData *data, + std::shared_ptr dataBuffer, const StreamData *ext) +{ + DHLOGI("%s: ProcessDirtyData.", LOG_TAG); + std::shared_ptr listener = channelListener_.lock(); + if (listener == nullptr) { + DHLOGE("%s: Channel listener is null.", LOG_TAG); + return; + } + int32_t ret = memcpy_s(dataBuffer->Data(), dataBuffer->Capacity(), + reinterpret_cast(data->buf), data->bufLen); if (ret != EOK) { - DHLOGE("%s: Data memcpy_s failed", LOG_TAG); + DHLOGE("%s: Dirty data memcpy_s failed.", LOG_TAG); + return; + } + nlohmann::json rectJson = nlohmann::json::parse(ext->buf, nullptr, false); + if (rectJson.is_discarded()) { + DHLOGE("%s: OnStreamReceived rectJson invalid", LOG_TAG); + return; + } + if (!IsInt32(rectJson, "dirtySize") || !IsInt32(rectJson, "dataType")) { return; } + int32_t dirtySize = rectJson["dirtySize"].get(); + int32_t dataType = rectJson["dataType"].get(); + uint8_t num = 0; + while (num < dirtySize) { + auto item = std::to_string(num); + if (!rectJson.contains(item)) { + return; + } + int32_t X = rectJson[item][0].get(); + int32_t Y = rectJson[item][1].get(); + int32_t W = rectJson[item][2].get(); + int32_t H = rectJson[item][3].get(); + int32_t Size = rectJson[item][4].get(); + DirtyRect rect = {X, Y, W, H, Size}; + dataBuffer->AddDirtyRect(rect); + num++; + } + dataBuffer->SetDataType(dataType); listener->OnDataReceived(dataBuffer); } } // namespace DistributedHardware diff --git a/services/screentransport/screensinkprocessor/decoder/include/image_sink_decoder.h b/services/screentransport/screensinkprocessor/decoder/include/image_sink_decoder.h index 1e4b1cbef38e26c1230f9e1bff721702b33e6e3e..2d9b181ff316b577dcee64cd1d75460b4edab51e 100644 --- a/services/screentransport/screensinkprocessor/decoder/include/image_sink_decoder.h +++ b/services/screentransport/screensinkprocessor/decoder/include/image_sink_decoder.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-2023 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 @@ -28,6 +28,7 @@ #include "media_errors.h" #include "format.h" #include "surface.h" +#include "iconsumer_surface.h" #include "data_buffer.h" #include "iimage_sink_processor_listener.h" @@ -36,6 +37,15 @@ namespace OHOS { namespace DistributedHardware { +class ConsumBufferListener : public IBufferConsumerListener { +public: + ConsumBufferListener(const std::shared_ptr decoder) : decoder_(decoder) {}; + ~ConsumBufferListener() = default; + void OnBufferAvailable() override; +private: + static const constexpr char *LOG_TAG = "ConsumBufferListener"; + std::shared_ptr decoder_; +}; class ImageSinkDecoder : public std::enable_shared_from_this { public: explicit ImageSinkDecoder(const std::shared_ptr &imageListener) @@ -48,6 +58,12 @@ public: int32_t StopDecoder(); int32_t SetOutputSurface(sptr &surface); int32_t InputScreenData(const std::shared_ptr &data); + int32_t AddSurface(); + void ConsumeSurface(); + uint8_t *GetLastFrame(); + sptr GetWinSurfaceBuffer(); + void NormalProcess(sptr surfaceBuffer, sptr windowSurfaceBuffer); + void OffsetProcess(sptr surfaceBuffer, sptr windowSurfaceBuffer); void OnError(Media::AVCodecErrorType errorType, int32_t errorCode); void OnInputBufferAvailable(uint32_t index); @@ -64,16 +80,23 @@ private: private: static const constexpr char *LOG_TAG = "ImageSinkDecoder"; - + VideoParam configParam_; std::mutex dataMutex_; std::mutex decodeMutex_; std::thread decodeThread_; std::condition_variable decodeCond_; + uint8_t *lastFrame_ = nullptr; + int32_t lastFrameSize_ = 0; Media::Format imageFormat_; Media::AVCodecBufferInfo decoderBufferInfo_; bool isDecoderReady_ = false; + int32_t alignedHeight_ = 0; + sptr consumerSurface_; + sptr producerSurface_; + sptr windowSurface_; + sptr consumerBufferListener_; std::queue> videoDataQueue_; std::queue bufferIndexQueue_; std::shared_ptr videoDecoder_; diff --git a/services/screentransport/screensinkprocessor/decoder/src/image_sink_decoder.cpp b/services/screentransport/screensinkprocessor/decoder/src/image_sink_decoder.cpp index 6fc23bb7d0f2c6b6d06b0a15e2ae5c6ba7c6c561..687c25271c63243749f75700ed6b824200761f23 100644 --- a/services/screentransport/screensinkprocessor/decoder/src/image_sink_decoder.cpp +++ b/services/screentransport/screensinkprocessor/decoder/src/image_sink_decoder.cpp @@ -41,10 +41,179 @@ int32_t ImageSinkDecoder::ConfigureDecoder(const VideoParam &configParam) DHLOGE("%s: SetDecoderFormat failed.", LOG_TAG); return ret; } + configParam_ = configParam; + ret = AddSurface(); + if (ret != DH_SUCCESS) { + DHLOGE("%s: Add surface failed ret: %." PRId32, LOG_TAG, ret); + consumerSurface_ = nullptr; + producerSurface_ = nullptr; + return ret; + } + alignedHeight_ = configParam_.GetVideoHeight(); + if (alignedHeight_ % ALIGNEDBITS != 0) { + alignedHeight_ = ((alignedHeight_ / ALIGNEDBITS) + 1) * ALIGNEDBITS; + } + return DH_SUCCESS; +} + +int32_t ImageSinkDecoder::AddSurface() +{ + DHLOGI("%s: AddSurface.", LOG_TAG); + consumerSurface_ = IConsumerSurface::Create(); + if (consumerSurface_ == nullptr) { + DHLOGE("%s: Create consumer surface failed.", LOG_TAG); + return ERR_DH_SCREEN_CODEC_SURFACE_ERROR; + } + + sptr producer = consumerSurface_->GetProducer(); + if (producer == nullptr) { + DHLOGE("%s: Get preducer surface failed.", LOG_TAG); + return ERR_DH_SCREEN_CODEC_SURFACE_ERROR; + } + + producerSurface_ = Surface::CreateSurfaceAsProducer(producer); + if (producerSurface_ == nullptr) { + DHLOGE("%s: Create preducer surface failed.", LOG_TAG); + return ERR_DH_SCREEN_CODEC_SURFACE_ERROR; + } + if (consumerBufferListener_ == nullptr) { + consumerBufferListener_ = new ConsumBufferListener(shared_from_this()); + } + consumerSurface_->RegisterConsumerListener(consumerBufferListener_); + lastFrameSize_ = configParam_.GetVideoWidth() * configParam_.GetVideoHeight() * RGB_CHROMA / TWO; + lastFrame_ = new uint8_t[lastFrameSize_]; return DH_SUCCESS; } +uint8_t *ImageSinkDecoder::GetLastFrame() +{ + return lastFrame_; +} + +sptr ImageSinkDecoder::GetWinSurfaceBuffer() +{ + DHLOGI("%s: GetWinSurfaceBuffer.", LOG_TAG); + sptr windowSurfaceBuffer = nullptr; + int32_t releaseFence = -1; + OHOS::BufferRequestConfig requestConfig = { + .width = configParam_.GetVideoWidth(), + .height = configParam_.GetVideoHeight(), + .strideAlignment = STRIDE_ALIGNMENT, + .format = PIXEL_FMT_YCBCR_420_SP, + .usage = HBM_USE_CPU_READ | HBM_USE_CPU_WRITE | HBM_USE_MEM_DMA, + }; + SurfaceError surfaceErr = windowSurface_->RequestBuffer(windowSurfaceBuffer, releaseFence, requestConfig); + if (surfaceErr != SURFACE_ERROR_OK || windowSurfaceBuffer == nullptr) { + DHLOGE("%s: windowSurface_ request buffer failed, buffer is nullptr.", LOG_TAG); + windowSurface_->CancelBuffer(windowSurfaceBuffer); + } + return windowSurfaceBuffer; +} + +void ImageSinkDecoder::NormalProcess(sptr surfaceBuffer, sptr windowSurfaceBuffer) +{ + DHLOGI("%s: NormalProcess.", LOG_TAG); + auto surfaceAddr = static_cast(surfaceBuffer->GetVirAddr()); + auto windowSurfaceAddr = static_cast(windowSurfaceBuffer->GetVirAddr()); + int32_t sizeData = lastFrameSize_; + int32_t size = windowSurfaceBuffer->GetSize(); + int32_t ret = memcpy_s(windowSurfaceAddr, size, surfaceAddr, sizeData); + if (ret != EOK) { + DHLOGE("%s: surfaceBuffer memcpy run failed.", LOG_TAG); + windowSurface_->CancelBuffer(windowSurfaceBuffer); + } +} + +void ImageSinkDecoder::OffsetProcess(sptr surfaceBuffer, sptr windowSurfaceBuffer) +{ + DHLOGI("%s: OffsetProcess.", LOG_TAG); + auto surfaceAddr = static_cast(surfaceBuffer->GetVirAddr()); + auto windowSurfaceAddr = static_cast(windowSurfaceBuffer->GetVirAddr()); + int32_t size = windowSurfaceBuffer->GetSize(); + int32_t srcDataOffset = 0; + int32_t dstDataOffset = 0; + int32_t alignedWidth = surfaceBuffer->GetStride(); + int32_t chromaOffset = configParam_.GetVideoWidth() * configParam_.GetVideoHeight(); + for (int32_t yh = 0 ; yh < configParam_.GetVideoHeight() ; yh++) { + int32_t ret = memcpy_s(windowSurfaceAddr + dstDataOffset, chromaOffset - dstDataOffset, + surfaceAddr + srcDataOffset, configParam_.GetVideoWidth()); + if (ret != EOK) { + DHLOGE("%s: surfaceBuffer memcpy_s run failed.", LOG_TAG); + windowSurface_->CancelBuffer(windowSurfaceBuffer); + return; + } + dstDataOffset += configParam_.GetVideoWidth(); + srcDataOffset += alignedWidth; + } + dstDataOffset = chromaOffset; + srcDataOffset = alignedWidth * alignedHeight_; + for (int32_t uvh = 0 ; uvh < configParam_.GetVideoHeight() / TWO; uvh++) { + int32_t ret = memcpy_s(windowSurfaceAddr + dstDataOffset, size - dstDataOffset, + surfaceAddr + srcDataOffset, configParam_.GetVideoWidth()); + if (ret != EOK) { + DHLOGE("%s: surfaceBuffer memcpy_s run failed.", LOG_TAG); + windowSurface_->CancelBuffer(windowSurfaceBuffer); + return; + } + dstDataOffset += configParam_.GetVideoWidth(); + srcDataOffset += alignedWidth; + } +} + +void ImageSinkDecoder::ConsumeSurface() +{ + DHLOGI("%s: ConsumeSurface.", LOG_TAG); + std::unique_lock bufLock(decodeMutex_); + if (consumerSurface_ == nullptr) { + DHLOGE("%s: consumerSurface_ is nullptr.", LOG_TAG); + return; + } + sptr surfaceBuffer = nullptr; + int32_t fence = -1; + int64_t timestamp = 0; + OHOS::Rect damage = {0, 0, 0, 0}; + SurfaceError surfaceErr = consumerSurface_->AcquireBuffer(surfaceBuffer, fence, timestamp, damage); + if (surfaceErr != SURFACE_ERROR_OK) { + return; + } + sptr windowSurfaceBuffer = GetWinSurfaceBuffer(); + if (windowSurfaceBuffer == nullptr) { + consumerSurface_->ReleaseBuffer(surfaceBuffer, -1); + return; + } + int32_t alignedWidth = surfaceBuffer->GetStride(); + if (alignedWidth == configParam_.GetVideoWidth() && alignedHeight_ == configParam_.GetVideoHeight()) { + NormalProcess(surfaceBuffer, windowSurfaceBuffer); + } else { + OffsetProcess(surfaceBuffer, windowSurfaceBuffer); + } + auto windowSurfaceAddr = static_cast(windowSurfaceBuffer->GetVirAddr()); + BufferFlushConfig flushConfig = { {0, 0, windowSurfaceBuffer->GetWidth(), windowSurfaceBuffer->GetHeight()}, 0}; + int32_t ret = memcpy_s(lastFrame_, lastFrameSize_, windowSurfaceAddr, lastFrameSize_); + if (ret != EOK) { + DHLOGE("%s: surfaceBuffer memcpy_s run failed.", LOG_TAG); + consumerSurface_->ReleaseBuffer(surfaceBuffer, -1); + windowSurface_->CancelBuffer(windowSurfaceBuffer); + return; + } + DHLOGI("%s: ConsumeSurface sucess, send NV12 to window.", LOG_TAG); + surfaceErr = windowSurface_->FlushBuffer(windowSurfaceBuffer, -1, flushConfig); + if (surfaceErr != SURFACE_ERROR_OK) { + DHLOGE("%s: windowSurface_ flush buffer failed.", LOG_TAG); + consumerSurface_->ReleaseBuffer(surfaceBuffer, -1); + windowSurface_->CancelBuffer(windowSurfaceBuffer); + return; + } + consumerSurface_->ReleaseBuffer(surfaceBuffer, -1); +} + +void ConsumBufferListener::OnBufferAvailable() +{ + DHLOGI("%s: OnBufferAvailable, receive NV12 data from decoder.", LOG_TAG); + decoder_->ConsumeSurface(); +} + int32_t ImageSinkDecoder::ReleaseDecoder() { DHLOGI("%s: ReleaseDecoder.", LOG_TAG); @@ -52,7 +221,9 @@ int32_t ImageSinkDecoder::ReleaseDecoder() DHLOGE("%s: Decoder is null.", LOG_TAG); return ERR_DH_SCREEN_TRANS_NULL_VALUE; } - + if (lastFrame_ != nullptr) { + delete [] lastFrame_; + } int32_t ret = videoDecoder_->Release(); if (ret != Media::MSERR_OK) { DHLOGE("%s: ReleaseDecoder failed.", LOG_TAG); @@ -206,13 +377,20 @@ int32_t ImageSinkDecoder::SetOutputSurface(sptr &surface) DHLOGE("%s: Decoder or surface is null.", LOG_TAG); return ERR_DH_SCREEN_TRANS_NULL_VALUE; } - - int32_t ret = videoDecoder_->SetOutputSurface(surface); - if (ret != Media::MSERR_OK) { - DHLOGE("%s: SetOutputSurface failed.", LOG_TAG); - return ERR_DH_SCREEN_CODEC_SURFACE_ERROR; + windowSurface_ = surface; + if (consumerSurface_ == nullptr || producerSurface_ == nullptr) { + int32_t ret = videoDecoder_->SetOutputSurface(surface); + if (ret != Media::MSERR_OK) { + DHLOGE("%s: SetOutputSurface failed.", LOG_TAG); + return ERR_DH_SCREEN_CODEC_SURFACE_ERROR; + } + } else { + int32_t ret = videoDecoder_->SetOutputSurface(producerSurface_); + if (ret != Media::MSERR_OK) { + DHLOGE("%s: SetOutputSurface failed.", LOG_TAG); + return ERR_DH_SCREEN_CODEC_SURFACE_ERROR; + } } - return DH_SUCCESS; } @@ -353,7 +531,7 @@ int32_t ImageSinkDecoder::ProcessData(const std::shared_ptr &screenD return ERR_DH_SCREEN_CODEC_SURFACE_ERROR; } - DHLOGD("%s: Decode screen data.", LOG_TAG); + DHLOGD("%s: Decode screen data. send data to H264 decoder", LOG_TAG); Media::AVCodecBufferInfo bufferInfo; bufferInfo.presentationTimeUs = 0; bufferInfo.size = static_cast(screenData->Capacity()); diff --git a/services/screentransport/screensinkprocessor/include/image_sink_processor.h b/services/screentransport/screensinkprocessor/include/image_sink_processor.h index 20ab7d27ce3ff8b889091a8155f5681743889804..b73e5694192a65620f8848febfd8c648dd079944 100644 --- a/services/screentransport/screensinkprocessor/include/image_sink_processor.h +++ b/services/screentransport/screensinkprocessor/include/image_sink_processor.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-2023 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 @@ -20,6 +20,7 @@ #include "image_sink_decoder.h" #include "video_param.h" #include "data_buffer.h" +#include "jpeg_image_processor.h" namespace OHOS { namespace DistributedHardware { @@ -40,7 +41,8 @@ private: static const constexpr char *LOG_TAG = "ImageSinkProcessor"; VideoParam localParam_; VideoParam remoteParam_; - std::shared_ptr imageDecoder_; + std::shared_ptr imageDecoder_ = nullptr; + std::shared_ptr imageJpeg_ = nullptr; }; } // namespace DistributedHardware } // namespace OHOS diff --git a/services/screentransport/screensinkprocessor/src/image_sink_processor.cpp b/services/screentransport/screensinkprocessor/src/image_sink_processor.cpp index b9340ae01e0c39ceb6c9a5ec2b829eeb63a4810a..f17ccbd17f3432c008b25d740dd1ac08ad2aa6f1 100644 --- a/services/screentransport/screensinkprocessor/src/image_sink_processor.cpp +++ b/services/screentransport/screensinkprocessor/src/image_sink_processor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-2023 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 @@ -31,7 +31,7 @@ int32_t ImageSinkProcessor::ConfigureImageProcessor( remoteParam_ = remoteParam; imageDecoder_ = std::make_shared(imageListener); - + imageJpeg_ = std::make_shared(remoteParam); int32_t ret = imageDecoder_->ConfigureDecoder(localParam); if (ret != DH_SUCCESS) { DHLOGE("%s: ConfigureDecoder failed ret:%" PRId32, LOG_TAG, ret); @@ -120,6 +120,12 @@ int32_t ImageSinkProcessor::SetImageSurface(sptr &surface) return ret; } + ret = imageJpeg_->SetOutputSurface(surface); + if (ret != DH_SUCCESS) { + DHLOGE("%s: imageJpeg SetImageSurface failed ret: %" PRId32, LOG_TAG, ret); + ReportOptFail(DSCREEN_OPT_FAIL, ret, "imageJpeg SetOutputSurface failed."); + return ret; + } return DH_SUCCESS; } @@ -132,13 +138,24 @@ int32_t ImageSinkProcessor::ProcessImage(const std::shared_ptr &data return ERR_DH_SCREEN_TRANS_NULL_VALUE; } - int32_t ret = imageDecoder_->InputScreenData(data); - if (ret != DH_SUCCESS) { - DHLOGE("%s: InputScreenData failed ret:%" PRId32, LOG_TAG, ret); - ReportOptFail(DSCREEN_OPT_FAIL, ret, "InputScreenData failed."); - return ret; + if (data->DataType() == VIDEO_FULL_SCREEN_DATA) { + int32_t ret = imageDecoder_->InputScreenData(data); + if (ret != DH_SUCCESS) { + DHLOGE("%s: InputScreenData failed ret:%" PRId32, LOG_TAG, ret); + ReportOptFail(DSCREEN_OPT_FAIL, ret, "InputScreenData failed."); + return ret; + } + } else if (data->DataType() == VIDEO_PART_SCREEN_DATA) { + int32_t ret = imageJpeg_->FillDirtyImages2Surface(data, imageDecoder_->GetLastFrame()); + if (ret != DH_SUCCESS) { + DHLOGE("%s: FillDirtyImages2Surface failed ret:%" PRId32, LOG_TAG, ret); + ReportOptFail(DSCREEN_OPT_FAIL, ret, "FillDirtyImages2Surface failed."); + return ret; + } + } else { + DHLOGE("%s: data type is invalid.", LOG_TAG); + return ERR_DH_SCREEN_DATA_TYPE_INVALID; } - return DH_SUCCESS; } } // namespace DistributedHardware diff --git a/services/screentransport/screensinktrans/BUILD.gn b/services/screentransport/screensinktrans/BUILD.gn index e7b4ad805b238567168453000579aa0362967b21..15dc171b491707d45491bbaa340a7840dc06628d 100644 --- a/services/screentransport/screensinktrans/BUILD.gn +++ b/services/screentransport/screensinktrans/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2022 Huawei Device Co., Ltd. +# Copyright (c) 2022-2023 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 @@ -20,9 +20,9 @@ ohos_shared_library("distributed_screen_sinktrans") { include_dirs = [ "//base/hiviewdfx/hisysevent/interfaces/native/innerkits/hisysevent/include", "//third_party/json/include", + "//third_party/libjpeg", "//foundation/graphic/graphic_2d/interfaces/innerkits/surface", "${fwk_common_path}/utils/include", - "//base/hiviewdfx/hitrace/interfaces/native/innerkits/include/hitrace_meter", "${fwk_interfaces_path}/inner_kits/include", "${ipc_interfaces_path}/innerkits/ipc_core/include", "${services_path}/common/utils/include", @@ -32,17 +32,21 @@ ohos_shared_library("distributed_screen_sinktrans") { "./include", "${common_path}/include", "${services_path}/common/databuffer/include", + "${services_path}/common/imageJpeg/include", "${services_path}/common/screen_channel/include", "${services_path}/common/utils/include", "${services_path}/screentransport/screendatachannel/include", "${services_path}/screentransport/screensinktrans/include", "${services_path}/screentransport/screensinkprocessor/include", "${services_path}/screentransport/screensinkprocessor/decoder/include", + "${services_path}/screentransport/screensourceprocessor/include", "${services_path}/softbusadapter/include", ] sources = [ + "${common_path}/src/dscreen_json_util.cpp", "${services_path}/common/databuffer/src/data_buffer.cpp", + "${services_path}/common/imageJpeg/src/jpeg_image_processor.cpp", "${services_path}/common/utils/src/dscreen_fwkkit.cpp", "${services_path}/common/utils/src/video_param.cpp", "${services_path}/screentransport/screendatachannel/src/screen_data_channel_impl.cpp", @@ -57,8 +61,15 @@ ohos_shared_library("distributed_screen_sinktrans") { "${common_path}:distributed_screen_utils", "${distributedhardwarefwk_path}/interfaces/inner_kits:libdhfwk_sdk", "//foundation/graphic/graphic_2d/frameworks/surface:surface", + "//third_party/libjpeg-turbo:turbojpeg_static", ] + if (!distributed_screen_common) { + cflags = [ "-DLIBYUV" ] + include_dirs += [ "//third_party/libyuv/files/include" ] + deps += [ "//third_party/libyuv:yuv" ] + } + defines = [ "HI_LOG_ENABLE", "DH_LOG_TAG=\"dscreensinktrans\"", diff --git a/services/screentransport/screensinktrans/include/iscreen_sink_trans.h b/services/screentransport/screensinktrans/include/iscreen_sink_trans.h index ad0f37880e972c57ea66350f1651d6b0741fca23..9b3857d8c80095d0ef516acf79ce127709181b1b 100644 --- a/services/screentransport/screensinktrans/include/iscreen_sink_trans.h +++ b/services/screentransport/screensinktrans/include/iscreen_sink_trans.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-2023 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 @@ -34,6 +34,7 @@ public: virtual int32_t Stop() = 0; virtual int32_t RegisterStateCallback(const std::shared_ptr &callBack) = 0; virtual int32_t SetImageSurface(const sptr &surface) = 0; + virtual void SetScreenVersion(std::string &version) = 0; }; } // namespace DistributedHardware } // namespace OHOS diff --git a/services/screentransport/screensinktrans/include/screen_sink_trans.h b/services/screentransport/screensinktrans/include/screen_sink_trans.h index 807eb932cd293358077177bb09d0f4c597feefd6..8738684ed5cd24ee72bf24a4597d1fed7f27a1e4 100644 --- a/services/screentransport/screensinktrans/include/screen_sink_trans.h +++ b/services/screentransport/screensinktrans/include/screen_sink_trans.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-2023 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 @@ -40,6 +40,7 @@ public: int32_t Stop() override; int32_t RegisterStateCallback(const std::shared_ptr &callback) override; int32_t SetImageSurface(const sptr &surface) override; + void SetScreenVersion(std::string &version) override; void OnSessionOpened() override; void OnSessionClosed() override; @@ -57,6 +58,7 @@ private: private: static const constexpr char *LOG_TAG = "ScreenSinkTrans"; + std::string version_ = "1.0"; sptr decoderSurface_; std::shared_ptr imageProcessor_; std::shared_ptr screenChannel_; diff --git a/services/screentransport/screensinktrans/src/screen_sink_trans.cpp b/services/screentransport/screensinktrans/src/screen_sink_trans.cpp index a0795f8c3f4cc984b440ab0d91b2740c36ca950e..03d88dbbe7e6d6337f7c09ecc08ea4ac761ab5eb 100644 --- a/services/screentransport/screensinktrans/src/screen_sink_trans.cpp +++ b/services/screentransport/screensinktrans/src/screen_sink_trans.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-2023 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 @@ -23,7 +23,6 @@ #include "dscreen_log.h" #include "image_sink_processor.h" #include "screen_data_channel_impl.h" - namespace OHOS { namespace DistributedHardware { int32_t ScreenSinkTrans::SetUp(const VideoParam &localParam, const VideoParam &remoteParam, @@ -210,7 +209,9 @@ int32_t ScreenSinkTrans::InitScreenTrans(const VideoParam &localParam, const Vid const std::string &peerDevId) { screenChannel_ = std::make_shared(peerDevId); - + if (atoi(version_.c_str()) == TWO) { + screenChannel_->SetJpegSessionFlag(true); + } int32_t ret = RegisterChannelListener(); if (ret != DH_SUCCESS) { DHLOGE("%s: Register channel listener failed.", LOG_TAG); @@ -286,7 +287,7 @@ void ScreenSinkTrans::OnSessionOpened() if (dhFwkKit != nullptr) { int32_t ret = dhFwkKit->PublishMessage(DHTopic::TOPIC_LOW_LATENCY, ENABLE_LOW_LATENCY.dump()); if (ret != DH_FWK_SUCCESS) { - DHLOGE("%s: Sink start enable low latency failed ret: %d.", LOG_TAG, ret); + DHLOGE("%s: Sink start enable low latency failed ret: %." PRId32, LOG_TAG, ret); } } } @@ -298,7 +299,7 @@ void ScreenSinkTrans::OnSessionClosed() if (dhFwkKit != nullptr) { int32_t ret = dhFwkKit->PublishMessage(DHTopic::TOPIC_LOW_LATENCY, DISABLE_LOW_LATENCY.dump()); if (ret != DH_FWK_SUCCESS) { - DHLOGE("%s: Sink stop enable low latency failed ret: %d.", LOG_TAG, ret); + DHLOGE("%s: Sink stop enable low latency failed ret: %." PRId32, LOG_TAG, ret); } } @@ -323,6 +324,11 @@ void ScreenSinkTrans::OnDataReceived(const std::shared_ptr &data) } } +void ScreenSinkTrans::SetScreenVersion(std::string &version) +{ + version_ = version; +} + void ScreenSinkTrans::OnProcessorStateNotify(int32_t state) { DHLOGI("%s: OnProcessorStateNotify.", LOG_TAG); diff --git a/services/screentransport/screensourceprocessor/encoder/include/idscreen_dbg_itf.h b/services/screentransport/screensourceprocessor/encoder/include/idscreen_dbg_itf.h new file mode 100644 index 0000000000000000000000000000000000000000..a60aa87026cf920a8e771621daa49441486d14b1 --- /dev/null +++ b/services/screentransport/screensourceprocessor/encoder/include/idscreen_dbg_itf.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2023 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OHOS_DSCREEN_DBG_ITF_H +#define OHOS_DSCREEN_DBG_ITF_H + +#include +#include + +namespace OHOS { +namespace DistributedHardware { +const std::string GET_DBG_ITF_FUNC = "GetDBGItf"; +const std::string GET_IMAGE_DIRTY_FUNC = "GetImageSetDirty"; +class IDScreenDBGItf { +public: + virtual int32_t Init() = 0; + virtual int32_t Release() = 0; +}; +class IImageSetDirty { +public: + virtual void SetDamage(std::vector> dirtyVecs) = 0; + virtual std::vector> GetDamage() = 0; +}; +extern "C" __attribute__((visibility("default"))) IDScreenDBGItf *GetDBGItf(); +extern "C" __attribute__((visibility("default"))) IImageSetDirty *GetImageSetDirty(); +} +} +#endif \ No newline at end of file diff --git a/services/screentransport/screensourceprocessor/encoder/include/image_source_encoder.h b/services/screentransport/screensourceprocessor/encoder/include/image_source_encoder.h index d5a6dfe2304a7af1320e8fff3eb8cadd03b65278..e843c8a38a4be03ba4a67c09f47bb7fef1fce522 100644 --- a/services/screentransport/screensourceprocessor/encoder/include/image_source_encoder.h +++ b/services/screentransport/screensourceprocessor/encoder/include/image_source_encoder.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-2023 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 @@ -17,6 +17,7 @@ #define OHOS_IMAGE_SOURCE_ENCODER_H #include +#include #include "avsharedmemory.h" #include "avcodec_video_encoder.h" @@ -24,13 +25,24 @@ #include "media_errors.h" #include "format.h" #include "surface.h" +#include "iconsumer_surface.h" +#include "idscreen_dbg_itf.h" #include "iimage_source_processor_listener.h" #include "image_encoder_callback.h" #include "video_param.h" namespace OHOS { namespace DistributedHardware { +class ConsumerBufferListener : public IBufferConsumerListener { +public: + explicit ConsumerBufferListener(const std::shared_ptr encoder) : encoder_(encoder) {}; + ~ConsumerBufferListener() = default; + void OnBufferAvailable() override; +private: + static const constexpr char *LOG_TAG = "ConsumerBufferListener"; + std::shared_ptr encoder_; +}; class ImageSourceEncoder : public std::enable_shared_from_this { public: explicit ImageSourceEncoder(const std::shared_ptr &imageListener) @@ -41,15 +53,17 @@ public: int32_t ReleaseEncoder(); int32_t StartEncoder(); int32_t StopEncoder(); - sptr &GetInputSurface() - { - return videoSurface_; - } - + int32_t AddSurface(); + sptr &GetInputSurface(); void OnError(Media::AVCodecErrorType errorType, int32_t errorCode); void OnOutputBufferAvailable(uint32_t index, Media::AVCodecBufferInfo info, Media::AVCodecBufferFlag flag); void OnInputBufferAvailable(uint32_t index); void OnOutputFormatChanged(const Media::Format &format); + void ConsumeSurface(); + int32_t FeedEncoderData(sptr &surfaceBuffer); + sptr GetConsumerSurface(); + std::vector VecToDamage(std::vector> eventContent); + sptr GetEncoderInputSurfaceBuffer(); private: int32_t InitVideoEncoder(const VideoParam &configParam); @@ -60,12 +74,23 @@ private: Media::Format imageFormat_; Media::AVCodecBufferInfo encoderBufferInfo_; + VideoParam configParam_; - sptr videoSurface_; + sptr encoderSurface_; + sptr consumerSurface_; + sptr producerSurface_; + sptr consumerBufferListener_; + std::mutex bufferMtx_; std::shared_ptr videoEncoder_; std::shared_ptr videoSharedMemory_; std::shared_ptr encodeVideoCallback_; std::weak_ptr imageProcessorListener_; + std::vector> eventContent_; +private: + IDScreenDBGItf *dscreenDbgItfPtr_ = nullptr; + IImageSetDirty *imageSetDirtyPtr_ = nullptr; + void* pHandler_ = nullptr; + void InitDscreenDBG(); }; } // namespace DistributedHardware } // namespace OHOS diff --git a/services/screentransport/screensourceprocessor/encoder/src/image_source_encoder.cpp b/services/screentransport/screensourceprocessor/encoder/src/image_source_encoder.cpp index 12a9cc981eb3a2a69498277ed7103e61e1d6c218..ffb8ff6f4c3b0e6d484d9467a9bdd59906530946 100644 --- a/services/screentransport/screensourceprocessor/encoder/src/image_source_encoder.cpp +++ b/services/screentransport/screensourceprocessor/encoder/src/image_source_encoder.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-2023 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 @@ -15,37 +15,228 @@ #include "image_source_encoder.h" +#include +#include +#include #include +#include #include +#include +#include +#include "display_type.h" #include "dscreen_constants.h" #include "dscreen_errcode.h" #include "dscreen_hisysevent.h" #include "dscreen_log.h" - +#include "jpeglib.h" +#ifdef __LP64__ +const std::string LIB_LOAD_PATH = "/system/lib64/libdistributed_screen_dbg_itf.z.so"; +#else +const std::string LIB_LOAD_PATH = "/system/lib/libdistributed_screen_dbg_itf.z.so"; +#endif +using GetDscreenDBGItfFunc = OHOS::DistributedHardware::IDScreenDBGItf* (*)(); +using GetImageDirtyFunc = OHOS::DistributedHardware::IImageSetDirty* (*)(); namespace OHOS { namespace DistributedHardware { +void ConsumerBufferListener::OnBufferAvailable() +{ + DHLOGI("%s: OnBufferAvailable, receiv data from RS.", LOG_TAG); + encoder_->ConsumeSurface(); +} + +void ImageSourceEncoder::InitDscreenDBG() +{ + char path[PATH_MAX + 1] = {0x00}; + if (LIB_LOAD_PATH.length() > PATH_MAX || realpath(LIB_LOAD_PATH.c_str(), path) == nullptr) { + DHLOGE("File connicailization failed."); + return; + } + pHandler_ = dlopen(path, RTLD_LAZY | RTLD_NODELETE | RTLD_GLOBAL); + if (pHandler_ == nullptr) { + DHLOGE("%s: handler load failed, fail reason: %s.", path, dlerror()); + return; + } + GetDscreenDBGItfFunc getDscreenDBGItfFunc = (GetDscreenDBGItfFunc)dlsym(pHandler_, GET_DBG_ITF_FUNC.c_str()); + GetImageDirtyFunc getImageDirtyFunc = (GetImageDirtyFunc)dlsym(pHandler_, GET_IMAGE_DIRTY_FUNC.c_str()); + if (getDscreenDBGItfFunc == nullptr || getImageDirtyFunc ==nullptr) { + DHLOGE("get FUNC failed, failed reason: %s.", dlerror()); + return; + } + dscreenDbgItfPtr_ = getDscreenDBGItfFunc(); + imageSetDirtyPtr_ = getImageDirtyFunc(); + if (dscreenDbgItfPtr_ == nullptr || imageSetDirtyPtr_ == nullptr) { + DHLOGE("Get interface failed."); + return; + } + DHLOGI("InitDscreenDBG success."); + dscreenDbgItfPtr_->Init(); +} + +void ImageSourceEncoder::ConsumeSurface() +{ + DHLOGI("%s: ConsumeSurface.", LOG_TAG); + std::unique_lock bufLock(bufferMtx_); + if (consumerSurface_ == nullptr) { + DHLOGE("%s: consumerSurface_ is nullptr.", LOG_TAG); + return; + } + sptr surfaceBuffer = nullptr; + int32_t fence = -1; + int64_t timestamp = 0; + OHOS::Rect damage = {0, 0, 0, 0}; + SurfaceError surfaceErr = consumerSurface_->AcquireBuffer(surfaceBuffer, fence, timestamp, damage); + if (surfaceErr != SURFACE_ERROR_OK) { + DHLOGE("%s: consumerSurface_ acquire buffer failed, errcode: %" PRId32, LOG_TAG, surfaceErr); + consumerSurface_->ReleaseBuffer(surfaceBuffer, -1); + return; + } + if (pHandler_ != nullptr) { + eventContent_.clear(); + eventContent_ = imageSetDirtyPtr_->GetDamage(); + } + std::vector damages = VecToDamage(eventContent_); + std::shared_ptr listener = imageProcessorListener_.lock(); + if (listener == nullptr) { + DHLOGE("%s: Processor listener is null", LOG_TAG); + consumerSurface_->ReleaseBuffer(surfaceBuffer, -1); + return; + } + listener->OnDamageProcessDone(surfaceBuffer, damages); + consumerSurface_->ReleaseBuffer(surfaceBuffer, -1); +} + int32_t ImageSourceEncoder::ConfigureEncoder(const VideoParam &configParam) { DHLOGI("%s: ConfigureEncoder.", LOG_TAG); int32_t ret = InitVideoEncoder(configParam); if (ret != DH_SUCCESS) { - DHLOGE("%s: Init encoder failed ret:%" PRId32, LOG_TAG, ret); + DHLOGE("%s: Init encoder failed ret: %" PRId32, LOG_TAG, ret); return ret; } ret = SetEncoderFormat(configParam); if (ret != DH_SUCCESS) { - DHLOGE("%s: Set encoder format failed ret:%" PRId32, LOG_TAG, ret); + DHLOGE("%s: Set encoder format failed ret: %" PRId32, LOG_TAG, ret); return ret; } - videoSurface_ = videoEncoder_->CreateInputSurface(); - if (videoSurface_ == nullptr) { + encoderSurface_ = videoEncoder_->CreateInputSurface(); + if (encoderSurface_ == nullptr) { DHLOGE("%s: Create encoder surface failed.", LOG_TAG); return ERR_DH_SCREEN_CODEC_SURFACE_ERROR; } + configParam_ = configParam; + ret = AddSurface(); + if (ret != DH_SUCCESS) { + DHLOGE("%s: Add surface failed ret: %." PRId32, LOG_TAG, ret); + consumerSurface_ = nullptr; + producerSurface_ = nullptr; + return ret; + } + return DH_SUCCESS; +} +int32_t ImageSourceEncoder::AddSurface() +{ + DHLOGI("%s: AddSurface.", LOG_TAG); + consumerSurface_ = IConsumerSurface::Create(); + if (consumerSurface_ == nullptr) { + DHLOGE("%s: creat consumer surface failed.", LOG_TAG); + return ERR_DH_SCREEN_CODEC_SURFACE_ERROR; + } + sptr producer = consumerSurface_->GetProducer(); + if (producer == nullptr) { + DHLOGE("%s: Creat producer surface failed.", LOG_TAG); + return ERR_DH_SCREEN_CODEC_SURFACE_ERROR; + } + producerSurface_ = Surface::CreateSurfaceAsProducer(producer); + if (producerSurface_ == nullptr) { + DHLOGE("%s: Create preducer surface failed.", LOG_TAG); + return ERR_DH_SCREEN_CODEC_SURFACE_ERROR; + } + consumerBufferListener_ = new ConsumerBufferListener(shared_from_this()); + consumerSurface_->RegisterConsumerListener(consumerBufferListener_); + return DH_SUCCESS; +} + +sptr ImageSourceEncoder::GetConsumerSurface() +{ + DHLOGI("%s: GetConsumerSurface.", LOG_TAG); + return consumerSurface_; +} + +sptr &ImageSourceEncoder::GetInputSurface() +{ + DHLOGI("%s: GetInputSurface.", LOG_TAG); + if (producerSurface_ == nullptr) { + return encoderSurface_; + } + return producerSurface_; +} + +std::vector ImageSourceEncoder::VecToDamage(std::vector> eventContent) +{ + DHLOGI("%s: VecToDamage.", LOG_TAG); + std::vector damages; + for (auto item : eventContent) { + OHOS::Rect damage = {0, 0, 0, 0}; + damage.x = item[0]; + damage.y = item[1]; + damage.w = item[2]; + damage.h = item[3]; + damages.push_back(damage); + } + return damages; +} + +sptr ImageSourceEncoder::GetEncoderInputSurfaceBuffer() +{ + DHLOGI("%s: GetEncoderInputSurfaceBuffer.", LOG_TAG); + OHOS::BufferRequestConfig requestConfig; + requestConfig.width = configParam_.GetVideoWidth(); + requestConfig.height = configParam_.GetVideoHeight(); + requestConfig.usage = HBM_USE_CPU_READ | HBM_USE_CPU_WRITE | HBM_USE_MEM_DMA; + requestConfig.strideAlignment = STRIDE_ALIGNMENT; + requestConfig.format = PixelFormat::PIXEL_FMT_RGBA_8888; + requestConfig.timeout = 0; + sptr encoderSurfaceBuffer = nullptr; + int32_t releaseFence = -1; + SurfaceError surfaceErr = encoderSurface_->RequestBuffer(encoderSurfaceBuffer, releaseFence, requestConfig); + if (surfaceErr != GSERROR_OK || encoderSurfaceBuffer == nullptr) { + DHLOGE("%s: RequestBuffer failed.", LOG_TAG); + encoderSurface_->CancelBuffer(encoderSurfaceBuffer); + } + return encoderSurfaceBuffer; +} + +int32_t ImageSourceEncoder::FeedEncoderData(sptr &surfaceBuffer) +{ + sptr encoderSurfaceBuffer = GetEncoderInputSurfaceBuffer(); + if (encoderSurfaceBuffer == nullptr) { + DHLOGE("Get encoder input producer surface buffer failed."); + return ERR_DH_SCREEN_CODEC_SURFACE_ERROR; + } + int32_t screenDataSize = configParam_.GetVideoWidth() * configParam_.GetVideoHeight() * RGBA_CHROMA; + auto encoderSurfaceAddr = static_cast(encoderSurfaceBuffer->GetVirAddr()); + auto surfaceAddr = static_cast(surfaceBuffer->GetVirAddr()); + int32_t ret = memcpy_s(encoderSurfaceAddr, screenDataSize, surfaceAddr, screenDataSize); + if (ret != EOK) { + DHLOGE("%s: surfaceBuffer memcpy_s run failed.", LOG_TAG); + consumerSurface_->ReleaseBuffer(surfaceBuffer, -1); + encoderSurface_->CancelBuffer(encoderSurfaceBuffer); + return ret; + } + BufferFlushConfig flushConfig = { {0, 0, encoderSurfaceBuffer->GetWidth(), encoderSurfaceBuffer->GetHeight()}, 0}; + DHLOGI("%s: FeedEncoderData to H264 encoder.", LOG_TAG); + SurfaceError surfaceErr = encoderSurface_->FlushBuffer(encoderSurfaceBuffer, -1, flushConfig); + if (surfaceErr != SURFACE_ERROR_OK) { + DHLOGE("%s: encoderSurface_ flush buffer failed.", LOG_TAG); + consumerSurface_->ReleaseBuffer(surfaceBuffer, -1); + encoderSurface_->CancelBuffer(encoderSurfaceBuffer); + return surfaceErr; + } + consumerSurface_->ReleaseBuffer(surfaceBuffer, -1); return DH_SUCCESS; } @@ -62,9 +253,13 @@ int32_t ImageSourceEncoder::ReleaseEncoder() DHLOGE("%s: Release encoder failed.", LOG_TAG); return ERR_DH_SCREEN_CODEC_RELEASE_FAILED; } + if (pHandler_ != nullptr) { + dscreenDbgItfPtr_->Release(); + dlclose(pHandler_); + } encodeVideoCallback_ = nullptr; videoEncoder_ = nullptr; - + consumerBufferListener_ = nullptr; return DH_SUCCESS; } @@ -87,7 +282,7 @@ int32_t ImageSourceEncoder::StartEncoder() DHLOGE("%s: Start encoder failed.", LOG_TAG); return ERR_DH_SCREEN_CODEC_START_FAILED; } - + InitDscreenDBG(); return DH_SUCCESS; } @@ -109,7 +304,12 @@ int32_t ImageSourceEncoder::StopEncoder() DHLOGE("%s: Stop encoder failed.", LOG_TAG); return ERR_DH_SCREEN_CODEC_STOP_FAILED; } - + ret = consumerSurface_->UnregisterConsumerListener(); + if (ret != SURFACE_ERROR_OK) { + DHLOGE("Unregister Consumer Listener failed."); + } + consumerSurface_ = nullptr; + producerSurface_ = nullptr; return DH_SUCCESS; } @@ -212,7 +412,7 @@ void ImageSourceEncoder::OnError(Media::AVCodecErrorType errorType, int32_t erro void ImageSourceEncoder::OnOutputBufferAvailable(uint32_t index, Media::AVCodecBufferInfo info, Media::AVCodecBufferFlag flag) { - DHLOGD("%s: OnOutputBufferAvailable.", LOG_TAG); + DHLOGD("%s: OnOutputBufferAvailable, receiv H264 data from encoder.", LOG_TAG); std::shared_ptr listener = imageProcessorListener_.lock(); if (listener == nullptr) { DHLOGE("%s: Processor listener is null", LOG_TAG); @@ -241,8 +441,9 @@ void ImageSourceEncoder::OnOutputBufferAvailable(uint32_t index, Media::AVCodecB DHLOGE("%s: Copy data failed.", LOG_TAG); return; } + dataBuf->SetDataType(VIDEO_FULL_SCREEN_DATA); + dataBuf->SetSize(dataSize); listener->OnImageProcessDone(dataBuf); - ret = videoEncoder_->ReleaseOutputBuffer(index); if (ret != Media::MSERR_OK) { DHLOGE("%s: videoEncoder ReleaseOutputBuffer failed.", LOG_TAG); diff --git a/services/screentransport/screensourceprocessor/include/iimage_source_processor.h b/services/screentransport/screensourceprocessor/include/iimage_source_processor.h index 06dad68e75c93ca95f7ced1c41f0d8c4cc777b1a..e488bca6d284dfad83d6653a0dcef9f544d7511c 100644 --- a/services/screentransport/screensourceprocessor/include/iimage_source_processor.h +++ b/services/screentransport/screensourceprocessor/include/iimage_source_processor.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-2023 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 @@ -17,7 +17,7 @@ #define OHOS_IIMAGE_SOURCE_PROCESSOR_H #include "surface.h" - +#include "surface_buffer.h" #include #include "data_buffer.h" @@ -35,7 +35,9 @@ public: virtual int32_t ReleaseImageProcessor() = 0; virtual int32_t StartImageProcessor() = 0; virtual int32_t StopImageProcessor() = 0; - virtual sptr &GetImageSurface() = 0; + virtual sptr GetImageSurface() = 0; + virtual sptr GetConsumerSurface() = 0; + virtual int32_t ProcessFullImage(sptr &surfaceBuffer) = 0; }; } // namespace DistributedHardware } // namespace OHOS diff --git a/services/screentransport/screensourceprocessor/include/iimage_source_processor_listener.h b/services/screentransport/screensourceprocessor/include/iimage_source_processor_listener.h index eab3f25a226944807104678fc6e67b8e39b9ecf6..2fe496af2029e1fd932d527d3961c7ca4ea93f76 100644 --- a/services/screentransport/screensourceprocessor/include/iimage_source_processor_listener.h +++ b/services/screentransport/screensourceprocessor/include/iimage_source_processor_listener.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-2023 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 @@ -17,7 +17,7 @@ #define OHOS_IIMAGE_SOURCE_PROCESSOR_LISTENER_H #include "data_buffer.h" - +#include "surface_buffer.h" namespace OHOS { namespace DistributedHardware { class IImageSourceProcessorListener { @@ -26,6 +26,7 @@ public: virtual void OnImageProcessDone(const std::shared_ptr &data) = 0; virtual void OnProcessorStateNotify(int32_t state) = 0; + virtual void OnDamageProcessDone(sptr &surfaceBuffer, const std::vector &damages) = 0; }; } // namespace DistributedHardware } // namsspace OHOS diff --git a/services/screentransport/screensourceprocessor/include/image_source_processor.h b/services/screentransport/screensourceprocessor/include/image_source_processor.h index d42fbd96697fd7ee898ecd1fbe0c42a67fa7f3f9..9a908537c66c78d1d21c089e2c1579884d4c75c3 100644 --- a/services/screentransport/screensourceprocessor/include/image_source_processor.h +++ b/services/screentransport/screensourceprocessor/include/image_source_processor.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-2023 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 @@ -33,7 +33,9 @@ public: int32_t ReleaseImageProcessor() override; int32_t StartImageProcessor() override; int32_t StopImageProcessor() override; - sptr &GetImageSurface() override; + sptr GetImageSurface() override; + sptr GetConsumerSurface() override; + int32_t ProcessFullImage(sptr &surfaceBuffer) override; private: static const constexpr char *LOG_TAG = "ImageSourceProcessor"; diff --git a/services/screentransport/screensourceprocessor/src/image_source_processor.cpp b/services/screentransport/screensourceprocessor/src/image_source_processor.cpp index dc46b5db25b4976acd34a77c54d8b310025ba717..34c4bfcf37b7da813cbcf60b77b6624451e2fc28 100644 --- a/services/screentransport/screensourceprocessor/src/image_source_processor.cpp +++ b/services/screentransport/screensourceprocessor/src/image_source_processor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-2023 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 @@ -101,10 +101,31 @@ int32_t ImageSourceProcessor::StopImageProcessor() return DH_SUCCESS; } -sptr &ImageSourceProcessor::GetImageSurface() +sptr ImageSourceProcessor::GetImageSurface() { DHLOGI("%s: GetImageSurface.", LOG_TAG); return imageEncoder_->GetInputSurface(); } + +sptr ImageSourceProcessor::GetConsumerSurface() +{ + DHLOGI("%s: GetConsumerSurface.", LOG_TAG); + return imageEncoder_->GetConsumerSurface(); +} + +int32_t ImageSourceProcessor::ProcessFullImage(sptr &surfaceBuffer) +{ + DHLOGI("%s: ProcessFullImage.", LOG_TAG); + if (surfaceBuffer == nullptr) { + DHLOGE("%s: Process surfaceBuffer is null.", LOG_TAG); + return ERR_DH_SCREEN_SURFACE_BUFFER_INVALIED; + } + int32_t ret = imageEncoder_->FeedEncoderData(surfaceBuffer); + if (ret != DH_SUCCESS) { + DHLOGE("%s: FeedEncoderData failed.", LOG_TAG); + return ERR_DH_SCREEN_TRANS_ERROR; + } + return DH_SUCCESS; +} } // namespace DistributedHardware } // namespace OHOS \ No newline at end of file diff --git a/services/screentransport/screensourcetrans/BUILD.gn b/services/screentransport/screensourcetrans/BUILD.gn index e9893e8c797dc91dd038694a3903c06652684dfb..53502d741b6713e475fab95364a053d54bf496c6 100644 --- a/services/screentransport/screensourcetrans/BUILD.gn +++ b/services/screentransport/screensourcetrans/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2022 Huawei Device Co., Ltd. +# Copyright (c) 2022-2023 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 @@ -20,9 +20,8 @@ ohos_shared_library("distributed_screen_sourcetrans") { include_dirs = [ "//base/hiviewdfx/hisysevent/interfaces/native/innerkits/hisysevent/include", "//third_party/json/include", - "//foundation/graphic/graphic_2d/interfaces/innerkits/surface", + "//third_party/libjpeg-turbo", "${fwk_common_path}/utils/include", - "//base/hiviewdfx/hitrace/interfaces/native/innerkits/include/hitrace_meter", "${fwk_interfaces_path}/inner_kits/include", "${ipc_interfaces_path}/innerkits/ipc_core/include", "${services_path}/common/utils/include", @@ -38,10 +37,14 @@ ohos_shared_library("distributed_screen_sourcetrans") { "${services_path}/screentransport/screensourceprocessor/include", "${services_path}/screentransport/screensourceprocessor/encoder/include", "${services_path}/softbusadapter/include", + "${services_path}/common/imageJpeg/include", + "${services_path}/common/decision_center/include", ] sources = [ "${services_path}/common/databuffer/src/data_buffer.cpp", + "${services_path}/common/decision_center/src/screen_decision_center.cpp", + "${services_path}/common/imageJpeg/src/jpeg_image_processor.cpp", "${services_path}/common/utils/src/dscreen_fwkkit.cpp", "${services_path}/common/utils/src/video_param.cpp", "${services_path}/screentransport/screendatachannel/src/screen_data_channel_impl.cpp", @@ -56,8 +59,15 @@ ohos_shared_library("distributed_screen_sourcetrans") { "${common_path}:distributed_screen_utils", "${distributedhardwarefwk_path}/interfaces/inner_kits:libdhfwk_sdk", "//foundation/graphic/graphic_2d/frameworks/surface:surface", + "//third_party/libjpeg-turbo:turbojpeg_static", ] + if (!distributed_screen_common) { + cflags = [ "-DLIBYUV" ] + include_dirs += [ "//third_party/libyuv/files/include" ] + deps += [ "//third_party/libyuv:yuv" ] + } + defines = [ "HI_LOG_ENABLE", "DH_LOG_TAG=\"dscreensourcetrans\"", diff --git a/services/screentransport/screensourcetrans/include/iscreen_source_trans.h b/services/screentransport/screensourcetrans/include/iscreen_source_trans.h index 2b3c8e7ffac44f6668e91811b8d51f30775e78a7..528d67302949c90217be0eb02e11748a78d3cc1a 100644 --- a/services/screentransport/screensourcetrans/include/iscreen_source_trans.h +++ b/services/screentransport/screensourcetrans/include/iscreen_source_trans.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-2023 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 @@ -33,7 +33,10 @@ public: virtual int32_t Start() = 0; virtual int32_t Stop() = 0; virtual int32_t RegisterStateCallback(const std::shared_ptr &callBack) = 0; - virtual sptr &GetImageSurface() = 0; + virtual sptr GetImageSurface() = 0; + virtual int32_t SetConsumerSurface() = 0; + virtual void SetScreenVersion(std::string &version) = 0; + virtual std::string GetScreenVersion() = 0; }; } // namespace DistributedHardware } // namespace OHOS diff --git a/services/screentransport/screensourcetrans/include/screen_source_trans.h b/services/screentransport/screensourcetrans/include/screen_source_trans.h index 2d63fa10720995da757a2315115e204671bb1802..45bd7c8847ed33381d0cdf73e4401c7e44d574e8 100644 --- a/services/screentransport/screensourcetrans/include/screen_source_trans.h +++ b/services/screentransport/screensourcetrans/include/screen_source_trans.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-2023 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 @@ -23,6 +23,7 @@ #include #include +#include "screen_decision_center.h" #include "iimage_source_processor.h" #include "iscreen_source_trans.h" #include "iscreen_source_trans_callback.h" @@ -43,13 +44,17 @@ public: int32_t Start() override; int32_t Stop() override; int32_t RegisterStateCallback(const std::shared_ptr &callback) override; - sptr &GetImageSurface() override; + sptr GetImageSurface() override; void OnSessionOpened() override; void OnSessionClosed() override; void OnDataReceived(const std::shared_ptr &data) override; void OnImageProcessDone(const std::shared_ptr &data) override; void OnProcessorStateNotify(int32_t state) override; + void OnDamageProcessDone(sptr &surfaceBuffer, const std::vector &damages) override; + int32_t SetConsumerSurface() override; + void SetScreenVersion(std::string &version) override; + std::string GetScreenVersion() override; private: int32_t CheckVideoParam(const VideoParam ¶m); @@ -70,12 +75,14 @@ private: std::thread sendDataThread_; bool isChannelReady_ = false; - sptr encoderSurface_; + sptr consumerSurface_; std::queue> dataQueue_; std::shared_ptr imageProcessor_; std::shared_ptr screenChannel_; std::weak_ptr transCallback_; + std::shared_ptr screenDecisionCenter_; + std::string version_ = "1.0"; }; } // namespace DistributedHardware } // namespace OHOS diff --git a/services/screentransport/screensourcetrans/src/screen_source_trans.cpp b/services/screentransport/screensourcetrans/src/screen_source_trans.cpp index a43d57c5770f4ad4e7c5eb23c264fb203ba78475..66540c7f947c3f75702adfce9757001343632d8a 100644 --- a/services/screentransport/screensourcetrans/src/screen_source_trans.cpp +++ b/services/screentransport/screensourcetrans/src/screen_source_trans.cpp @@ -27,7 +27,6 @@ #include "dscreen_log.h" #include "image_source_processor.h" #include "screen_data_channel_impl.h" - namespace OHOS { namespace DistributedHardware { constexpr const char* FDATA_THREAD = "FeedDataThread"; @@ -40,17 +39,36 @@ int32_t ScreenSourceTrans::SetUp(const VideoParam &localParam, const VideoParam DHLOGE("%s: SetUp failed param error ret: %" PRId32, LOG_TAG, ret); return ret; } - ret = InitScreenTrans(localParam, remoteParam, peerDevId); if (ret != DH_SUCCESS) { DHLOGE("%s: SetUp failed ret: %" PRId32, LOG_TAG, ret); return ret; } - + ret = SetConsumerSurface(); + if (ret != DH_SUCCESS) { + DHLOGE("sourcetrans set image surface failed."); + return ret; + } + ret = screenDecisionCenter_->SetJpegSurface(consumerSurface_); + if (ret != DH_SUCCESS) { + DHLOGE("screenDecisionCenter set jpeg surface failed."); + return ret; + } DHLOGI("%s: SetUp success.", LOG_TAG); return DH_SUCCESS; } +int32_t ScreenSourceTrans::SetConsumerSurface() +{ + DHLOGI("%s: SetConsumerSurface.", LOG_TAG); + consumerSurface_ = imageProcessor_->GetConsumerSurface(); + if (consumerSurface_ == nullptr) { + DHLOGE("%s: consumerSurface is nullptr", LOG_TAG); + return ERR_DH_SCREEN_SURFACE_INVALIED; + } + return DH_SUCCESS; +} + int32_t ScreenSourceTrans::Release() { DHLOGI("%s: Release.", LOG_TAG); @@ -111,7 +129,7 @@ int32_t ScreenSourceTrans::Start() if (dhFwkKit != nullptr) { ret = dhFwkKit->PublishMessage(DHTopic::TOPIC_LOW_LATENCY, ENABLE_LOW_LATENCY.dump()); if (ret != DH_FWK_SUCCESS) { - DHLOGE("%s: Source start enable low latency failed ret: %d.", LOG_TAG, ret); + DHLOGE("%s: Source start enable low latency failed ret: %." PRId32, LOG_TAG, ret); } } @@ -140,7 +158,7 @@ int32_t ScreenSourceTrans::Stop() if (dhFwkKit != nullptr) { ret = dhFwkKit->PublishMessage(DHTopic::TOPIC_LOW_LATENCY, DISABLE_LOW_LATENCY.dump()); if (ret != DH_FWK_SUCCESS) { - DHLOGE("%s: Source stop enable low latency failed ret: %d.", LOG_TAG, ret); + DHLOGE("%s: Source stop enable low latency failed ret: %." PRId32, LOG_TAG, ret); } } @@ -176,10 +194,20 @@ int32_t ScreenSourceTrans::RegisterStateCallback(const std::shared_ptr &ScreenSourceTrans::GetImageSurface() +sptr ScreenSourceTrans::GetImageSurface() { DHLOGI("%s:GetImageSurface.", LOG_TAG); - return encoderSurface_; + return imageProcessor_->GetImageSurface(); +} + +void ScreenSourceTrans::SetScreenVersion(std::string &version) +{ + version_ = version; +} + +std::string ScreenSourceTrans::GetScreenVersion() +{ + return version_; } int32_t ScreenSourceTrans::CheckVideoParam(const VideoParam ¶m) @@ -234,9 +262,8 @@ int32_t ScreenSourceTrans::CheckTransParam(const VideoParam &localParam, const V DHLOGE("%s: check remoteParam param failed.", LOG_TAG); return ret; } - + DHLOGI("%s: Local: codecType(%u), videoFormat(%u), videoSize(%ux%u), screenSize(%ux%u).", LOG_TAG, - localParam.GetCodecType(), localParam.GetVideoFormat(), localParam.GetVideoWidth(), localParam.GetVideoHeight(), localParam.GetScreenWidth(), localParam.GetScreenHeight()); DHLOGI("%s: Remote: codecType(%u), videoFormat(%u), videoSize(%ux%u), screenSize(%ux%u).", LOG_TAG, remoteParam.GetCodecType(), remoteParam.GetVideoFormat(), remoteParam.GetVideoWidth(), @@ -249,16 +276,17 @@ int32_t ScreenSourceTrans::InitScreenTrans(const VideoParam &localParam, const V { DHLOGI("%s:InitScreenTrans.", LOG_TAG); screenChannel_ = std::make_shared(peerDevId); - + if (atoi(version_.c_str()) == TWO) { + screenChannel_->SetJpegSessionFlag(true); + } int32_t ret = RegisterChannelListener(); if (ret != DH_SUCCESS) { DHLOGE("%s: Register channel listener failed ret: %" PRId32, LOG_TAG, ret); screenChannel_ = nullptr; return ret; } - + screenDecisionCenter_ = std::make_shared(localParam); imageProcessor_ = std::make_shared(); - ret = RegisterProcessorListener(localParam, remoteParam); if (ret != DH_SUCCESS) { DHLOGE("%s: Register data processor listener failed ret: %" PRId32, LOG_TAG, ret); @@ -312,13 +340,11 @@ int32_t ScreenSourceTrans::RegisterProcessorListener(const VideoParam &localPara ReportOptFail(DSCREEN_OPT_FAIL, ret, "Config image processor failed."); return ret; } - - encoderSurface_ = imageProcessor_->GetImageSurface(); - if (encoderSurface_ == nullptr) { - DHLOGE("%s: Surface is null.", LOG_TAG); - return ERR_DH_SCREEN_TRANS_NULL_VALUE; + ret = screenDecisionCenter_->ConfigureDecisionCenter(listener, imageProcessor_); + if (ret != DH_SUCCESS) { + DHLOGE("%s: Config decision center failed ret: %" PRId32, LOG_TAG, ret); + return ret; } - return DH_SUCCESS; } @@ -364,9 +390,31 @@ void ScreenSourceTrans::OnDataReceived(const std::shared_ptr &data) DHLOGI("%s: OnChannelDataReceived source trans not support.", LOG_TAG); } +void ScreenSourceTrans::OnDamageProcessDone(sptr &surfaceBuffer, const std::vector &damages) +{ + DHLOGI("%s: OnDamageProcessDone.", LOG_TAG); + if (surfaceBuffer == nullptr) { + DHLOGE("%s: Trans surfaceBuffer is null.", LOG_TAG); + return; + } + int32_t ret = DH_SUCCESS; + switch (atoi(version_.c_str())) { + case OLD: + DHLOGI("%s: ProcessFullImage.", LOG_TAG); + ret = imageProcessor_->ProcessFullImage(surfaceBuffer); + break; + case NEW: + DHLOGI("%s: InputBufferImage.", LOG_TAG); + ret = screenDecisionCenter_->InputBufferImage(surfaceBuffer, damages); + break; + default: + break; + } +} + void ScreenSourceTrans::OnImageProcessDone(const std::shared_ptr &data) { - DHLOGD("%s: OnProcessorDataReceived received data from data processor.", LOG_TAG); + DHLOGD("%s: OnImageProcessDone.", LOG_TAG); std::lock_guard lck(dataQueueMtx_); while (dataQueue_.size() >= DATA_QUEUE_MAX_SIZE) { DHLOGE("%s: Data queue overflow.", LOG_TAG); @@ -420,7 +468,6 @@ void ScreenSourceTrans::FeedChannelData() if (ret != DH_SUCCESS) { DHLOGD("%s:Send data failed.", LOG_TAG); } - DHLOGD("%s: FeedChannelData success.", LOG_TAG); } } } // namespace DistributedHardware diff --git a/services/screentransport/test/unittest/screendatachannel/src/screen_data_channel_impl_test.cpp b/services/screentransport/test/unittest/screendatachannel/src/screen_data_channel_impl_test.cpp index a731ca5e8b53b9d2b025be8dd640afe5b5c512ae..e2e0cd0144ef6d37cdf42c5c578f2ce43c97792b 100644 --- a/services/screentransport/test/unittest/screendatachannel/src/screen_data_channel_impl_test.cpp +++ b/services/screentransport/test/unittest/screendatachannel/src/screen_data_channel_impl_test.cpp @@ -81,7 +81,7 @@ HWTEST_F(ScreenDataChannelImplTest, close_session_test_002, TestSize.Level1) { dataChannelImpl_->channelListener_ = std::make_shared(); - StreamData *ext = nullptr; + StreamData ext = {0}; StreamFrameInfo *param = nullptr; int32_t sessionId = 0; @@ -89,7 +89,7 @@ HWTEST_F(ScreenDataChannelImplTest, close_session_test_002, TestSize.Level1) data.buf = new char[DATA_LEN]; data.bufLen = DATA_LEN; - dataChannelImpl_->OnStreamReceived(sessionId, &data, ext, param); + dataChannelImpl_->OnStreamReceived(sessionId, &data, &ext, param); delete[] data.buf; dataChannelImpl_->sessionId_ = 0; EXPECT_EQ(ERR_DH_SCREEN_TRANS_SESSION_NOT_OPEN, dataChannelImpl_->CloseSession()); diff --git a/services/screentransport/test/unittest/screensinkprocessor/BUILD.gn b/services/screentransport/test/unittest/screensinkprocessor/BUILD.gn index d9a701be9af8a677036e8d4bd83229729ecc6f36..ea9e29592a550f7a5b5248bca20604e52982fc3a 100644 --- a/services/screentransport/test/unittest/screensinkprocessor/BUILD.gn +++ b/services/screentransport/test/unittest/screensinkprocessor/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2022 Huawei Device Co., Ltd. +# Copyright (c) 2022-2023 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 @@ -28,18 +28,19 @@ config("module_private_config") { include_dirs += [ "./include", - "${services_path}/screentransport/test/unittest/screentranstestutils/include", "${common_path}/include", "${services_path}/common/databuffer/include", + "${services_path}/common/imageJpeg/include", "${services_path}/common/screen_channel/include", "${services_path}/common/utils/include", + "${services_path}/softbusadapter/include", "${services_path}/screentransport/screendatachannel/include", - "${services_path}/screentransport/screensourcetrans/include", + "${services_path}/screentransport/screensinkprocessor/decoder/include", "${services_path}/screentransport/screensinkprocessor/include", "${services_path}/screentransport/screensinktrans/include", - "${services_path}/screentransport/screensinkprocessor/include", - "${services_path}/screentransport/screensinkprocessor/decoder/include", - "${services_path}/softbusadapter/include", + "${services_path}/screentransport/screensourcetrans/include", + "${services_path}/screentransport/screensourceprocessor/include", + "${services_path}/screentransport/test/unittest/screentranstestutils/include", ] } diff --git a/services/screentransport/test/unittest/screensinktrans/BUILD.gn b/services/screentransport/test/unittest/screensinktrans/BUILD.gn index 129f5edfaf918ac60e406e5220ea94d7878f5ac6..2725a6212d4e98d58a8a327a9ceda2b7911e562e 100644 --- a/services/screentransport/test/unittest/screensinktrans/BUILD.gn +++ b/services/screentransport/test/unittest/screensinktrans/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2022 Huawei Device Co., Ltd. +# Copyright (c) 2022-2023 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 @@ -28,18 +28,19 @@ config("module_private_config") { include_dirs += [ "./include", - "${services_path}/screentransport/test/unittest/screentranstestutils/include", "${common_path}/include", "${services_path}/common/databuffer/include", + "${services_path}/common/imageJpeg/include", "${services_path}/common/screen_channel/include", "${services_path}/common/utils/include", + "${services_path}/softbusadapter/include", "${services_path}/screentransport/screendatachannel/include", - "${services_path}/screentransport/screensourcetrans/include", - "${services_path}/screentransport/screensinktrans/include", - "${services_path}/screentransport/screensinkprocessor/include", "${services_path}/screentransport/screensinkprocessor/decoder/include", - "${services_path}/softbusadapter/include", - "//foundation/multimedia/player_framework/interfaces/inner_api/native", + "${services_path}/screentransport/screensinkprocessor/include", + "${services_path}/screentransport/screensinktrans/include", + "${services_path}/screentransport/screensourceprocessor/include", + "${services_path}/screentransport/screensourcetrans/include", + "${services_path}/screentransport/test/unittest/screentranstestutils/include", "//foundation/communication/dsoftbus/interfaces/kits/transport", "//foundation/graphic/graphic_2d/utils/buffer_handle/export", "//drivers/peripheral/base", diff --git a/services/screentransport/test/unittest/screensourcetrans/BUILD.gn b/services/screentransport/test/unittest/screensourcetrans/BUILD.gn index 0cff7b2da36a6bcfdc2746c54f030abb53ca3e5e..ccce9895926d5bc0473049da20bc53483398d49c 100644 --- a/services/screentransport/test/unittest/screensourcetrans/BUILD.gn +++ b/services/screentransport/test/unittest/screensourcetrans/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2022 Huawei Device Co., Ltd. +# Copyright (c) 2022-2023 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 @@ -29,27 +29,26 @@ config("module_private_config") { include_dirs += [ "./include", - "${services_path}/screentransport/test/unittest/screentranstestutils/include", "${common_path}/include", "${services_path}/common/databuffer/include", + "${services_path}/common/decision_center/include", + "${services_path}/common/imageJpeg/include", "${services_path}/common/screen_channel/include", "${services_path}/common/utils/include", "${services_path}/screentransport/screensinktrans/include", "${services_path}/screentransport/screensinkprocessor/include", - "${services_path}/screentransport/test/unittest/screensourcetrans/include", "${services_path}/screentransport/screensourcetrans/include", "${services_path}/screentransport/screendatachannel/include", "${services_path}/screentransport/screensourceprocessor/include", "${services_path}/screentransport/screensourceprocessor/encoder/include", + "${services_path}/screentransport/test/unittest/screensourcetrans/include", + "${services_path}/screentransport/test/unittest/screentranstestutils/include", "${services_path}/softbusadapter/include", - "//drivers/peripheral/display/interfaces/include", "//drivers/peripheral/base", "//foundation/communication/ipc/interfaces/innerkits/ipc_core/include", "//foundation/graphic/graphic_2d/interfaces/inner_api/surface", "//foundation/graphic/graphic_2d/interfaces/inner_api/common", "//foundation/graphic/graphic_2d/utils/buffer_handle/export", - "//foundation/multimedia/player_framework/interfaces/inner_api/native", - "//foundation/communication/dsoftbus/interfaces/kits/transport", ] } @@ -67,7 +66,11 @@ ohos_unittest("SourceTransTest") { "//third_party/googletest:gtest_main", ] - external_deps = [ "c_utils:utils" ] + external_deps = [ + "c_utils:utils", + "drivers_peripheral_display:hdi_display_device", + "multimedia_player_framework:media_client", + ] } group("source_trans_test") { diff --git a/services/screentransport/test/unittest/screensourcetrans/src/screen_source_trans_test.cpp b/services/screentransport/test/unittest/screensourcetrans/src/screen_source_trans_test.cpp index 0bce0f9e41570b34abab9b117e5ece49511b7663..fb111655b6d6930fe89c02662caeaceae6efcf65 100644 --- a/services/screentransport/test/unittest/screensourcetrans/src/screen_source_trans_test.cpp +++ b/services/screentransport/test/unittest/screensourcetrans/src/screen_source_trans_test.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-2023 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 @@ -70,9 +70,8 @@ HWTEST_F(ScreenSourceTransTest, SetUp_002, TestSize.Level1) remoteParam.SetVideoWidth(100); remoteParam.SetScreenHeight(100); remoteParam.SetScreenWidth(100); - std::string peerDevId = "peerDevId"; - int32_t actual = trans->SetUp(localParam, remoteParam, peerDevId); + int32_t actual = trans->SetUp(localParam, remoteParam, "peerDevId"); EXPECT_EQ(-1, actual); } @@ -406,10 +405,10 @@ HWTEST_F(ScreenSourceTransTest, GetImageSurface_001, TestSize.Level1) remoteParam.screenWidth_ = DSCREEN_MAX_SCREEN_DATA_WIDTH; remoteParam.screenHeight_ = DSCREEN_MAX_SCREEN_DATA_HEIGHT; trans->imageProcessor_ = std::make_shared(); + trans->screenDecisionCenter_ = std::make_shared(localParam); trans->RegisterProcessorListener(localParam, remoteParam); - sptr encoderSurface = trans->GetImageSurface(); - EXPECT_NE(nullptr, encoderSurface); + EXPECT_NE(nullptr, trans->GetImageSurface()); } /** diff --git a/services/screentransport/test/unittest/screentranstestutils/BUILD.gn b/services/screentransport/test/unittest/screentranstestutils/BUILD.gn index a9e7fafed01e9a9c6084ae4dc1108d9b79d01b92..c9a62057e90f54c18c4710dd33074674bdedb701 100644 --- a/services/screentransport/test/unittest/screentranstestutils/BUILD.gn +++ b/services/screentransport/test/unittest/screentranstestutils/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2022 Huawei Device Co., Ltd. +# Copyright (c) 2022-2023 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 @@ -32,17 +32,18 @@ config("module_private_config") { "${services_path}/screentransport/test/unittest/screentranstestutils/include", "${common_path}/include", "${services_path}/common/databuffer/include", + "${services_path}/common/decision_center/include", + "${services_path}/common/imageJpeg/include", "${services_path}/common/screen_channel/include", "${services_path}/common/utils/include", - "${services_path}/screentransport/screensinktrans/include", + "${services_path}/screentransport/screendatachannel/include", + "${services_path}/screentransport/screensinkprocessor/decoder/include", "${services_path}/screentransport/screensinkprocessor/include", - "${services_path}/screentransport/test/unittest/screensourcetrans/include", + "${services_path}/screentransport/screensinktrans/include", "${services_path}/screentransport/screensourcetrans/include", - "${services_path}/screentransport/screendatachannel/include", "${services_path}/screentransport/screensourceprocessor/include", "${services_path}/screentransport/screensourceprocessor/encoder/include", - "${services_path}/screentransport/screensinkprocessor/include", - "${services_path}/screentransport/screensinkprocessor/decoder/include", + "${services_path}/screentransport/test/unittest/screensourcetrans/include", "${services_path}/softbusadapter/include", "//drivers/peripheral/display/interfaces/include", "//drivers/peripheral/base", @@ -51,7 +52,6 @@ config("module_private_config") { "//foundation/graphic/graphic_2d/interfaces/inner_api/common", "//foundation/graphic/graphic_2d/utils/buffer_handle/export", "//foundation/multimedia/player_framework/interfaces/inner_api/native", - "//foundation/communication/dsoftbus/interfaces/kits/transport", ] } diff --git a/services/screentransport/test/unittest/screentranstestutils/include/screentrans_test_utils.h b/services/screentransport/test/unittest/screentranstestutils/include/screentrans_test_utils.h index 1bdee5eb5dba5f89d5ffff841a3a6802aca8dbe5..09cd1ce152beb86cdd6fab72a6f841dc8b7fe6ce 100644 --- a/services/screentransport/test/unittest/screentranstestutils/include/screentrans_test_utils.h +++ b/services/screentransport/test/unittest/screentranstestutils/include/screentrans_test_utils.h @@ -103,6 +103,10 @@ public: (void) data; return DH_SUCCESS; } + void SetJpegSessionFlag(bool flag) override + { + return; + } }; } // namespace DistributedHardware diff --git a/services/softbusadapter/src/softbus_adapter.cpp b/services/softbusadapter/src/softbus_adapter.cpp index 24828852092938cad6a2d03f15351bf24fe14ba8..e0e1efbe3896036a528813b535c4fddf2324151a 100644 --- a/services/softbusadapter/src/softbus_adapter.cpp +++ b/services/softbusadapter/src/softbus_adapter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2022-2023 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 @@ -158,13 +158,8 @@ int32_t SoftbusAdapter::OpenSoftbusSession(const std::string &mySessionName, con { DHLOGI("%s: OpenSoftbusSession mysess:%s peersess:%s id:%s.", LOG_TAG, mySessionName.c_str(), peerSessionName.c_str(), GetAnonyString(peerDevId).c_str()); - int dataType = TYPE_BYTES; - int streamType = -1; - if (mySessionName == DATA_SESSION_NAME) { - dataType = TYPE_STREAM; - streamType = RAW_STREAM; - } - + int dataType = TYPE_STREAM; + int streamType = COMMON_VIDEO_STREAM; SessionAttribute attr = { 0 }; attr.dataType = dataType; attr.linkTypeNum = LINK_TYPE_MAX; @@ -182,11 +177,11 @@ int32_t SoftbusAdapter::OpenSoftbusSession(const std::string &mySessionName, con attr.attr.streamAttr.streamType = streamType; int32_t sessionId = OpenSession(mySessionName.c_str(), peerSessionName.c_str(), peerDevId.c_str(), "0", &attr); if (sessionId < 0) { - DHLOGE("%s: OpenSession failed sessionId:%" PRId32, LOG_TAG, sessionId); + DHLOGE("%s: OpenSession failed sessionId: %." PRId32, LOG_TAG, sessionId); return ERR_DH_SCREEN_ADAPTER_OPEN_SESSION_FAIL; } - DHLOGI("%s: OpenSoftbusSession success sessionId:%" PRId32, LOG_TAG, sessionId); + DHLOGI("%s: OpenSoftbusSession success sessionId: %." PRId32, LOG_TAG, sessionId); return sessionId; }