diff --git a/common/include/dscreen_constants.h b/common/include/dscreen_constants.h index 12a128c9d11e0c2b3166af29679b53b6f91f12ef..101c26a197c4f54e0fe8c582b750c9eb692484f5 100644 --- a/common/include/dscreen_constants.h +++ b/common/include/dscreen_constants.h @@ -160,8 +160,6 @@ const std::string KEY_VIDEO_HEIGHT = "videoHeight"; const std::string KEY_COLOR_FORMAT = "colorFormat"; const std::string KEY_FPS = "fps"; const std::string KEY_CODECTYPE = "codecType"; -const std::string KEY_HISTREAMER_VIDEO_ENCODER = "histmVidEnc"; -const std::string KEY_HISTREAMER_VIDEO_DECODER = "histmVidDec"; const std::string SCREEN_CLIENT_WINDOW = "screenClientWindow"; const std::string KEY_DEV_ID = "devId"; const std::string KEY_DH_ID = "dhId"; diff --git a/screenhandler/src/dscreen_handler.cpp b/screenhandler/src/dscreen_handler.cpp index 349f7221b7bd725d0f7350ed5d4201b5f9d6a62b..7432ff80ac140b4a940dc16db45d84e9f6df11cd 100644 --- a/screenhandler/src/dscreen_handler.cpp +++ b/screenhandler/src/dscreen_handler.cpp @@ -30,6 +30,10 @@ using json = nlohmann::json; namespace OHOS { namespace DistributedHardware { +namespace { +const std::string KEY_HISTREAMER_VIDEO_ENCODER = "histmVidEnc"; +const std::string KEY_HISTREAMER_VIDEO_DECODER = "histmVidDec"; +} IMPLEMENT_SINGLE_INSTANCE(DScreenHandler); DScreenHandler::DScreenHandler() diff --git a/services/screenservice/sourceservice/BUILD.gn b/services/screenservice/sourceservice/BUILD.gn index 8f1519bf8b6e5328b3157e6ab392e9a3d1929c50..9ec4500d2cee48afa9aeb65cdf0be15889985fb3 100644 --- a/services/screenservice/sourceservice/BUILD.gn +++ b/services/screenservice/sourceservice/BUILD.gn @@ -21,6 +21,7 @@ ohos_shared_library("distributed_screen_source") { "//third_party/json/include", "//third_party/libjpeg-turbo", "${distributedhardwarefwk_path}/interfaces/inner_kits/include", + "${distributedhardwarefwk_path}/utils/include", "${fwk_common_path}/utils/include", ] @@ -75,6 +76,7 @@ ohos_shared_library("distributed_screen_source") { external_deps = [ "c_utils:utils", "distributed_hardware_fwk:distributed_av_sender", + "distributed_hardware_fwk:distributedhardwareutils", "distributed_hardware_fwk:libdhfwk_sdk", "graphic_standard:libcomposer", "graphic_standard:surface", diff --git a/services/screenservice/sourceservice/dscreenmgr/2.0/include/dscreen.h b/services/screenservice/sourceservice/dscreenmgr/2.0/include/dscreen.h index dc6cb63b5cabf493ac2d2bb1cc98b563c3f2475d..82b9767ff6006759a25c06615532900195e8661b 100644 --- a/services/screenservice/sourceservice/dscreenmgr/2.0/include/dscreen.h +++ b/services/screenservice/sourceservice/dscreenmgr/2.0/include/dscreen.h @@ -24,7 +24,10 @@ #include "surface.h" #include "iconsumer_surface.h" + #include "dscreen_constants.h" +#include "distributed_hardware_fwk_kit_paras.h" +#include "histreamer_ability_parser.h" #include "video_param.h" #include "av_sender_engine_adapter.h" @@ -105,7 +108,15 @@ private: void HandleDisconnect(); int32_t StartSenderEngine(); int32_t StopSenderEngine(); - int32_t NegotiateCodecType(const std::string &remoteCodecInfoStr); + + /* + * Negotiate the codec format between local to remote device, + * for DScreen, local encoder screen, remote decoder it. + * rmtDecoderStr: remote Decoder description in JSON format + */ + int32_t NegotiateCodecType(const std::string &rmtDecoderStr); + int32_t ChooseCodecType(const std::vector &localVideoEncoders, + const std::vector &rmtVideoDecoders); int32_t ConfigSurface(); int32_t RemoveSurface(); int32_t SetUp(); diff --git a/services/screenservice/sourceservice/dscreenmgr/2.0/src/dscreen.cpp b/services/screenservice/sourceservice/dscreenmgr/2.0/src/dscreen.cpp index 0619f73307bfd2fdc495e0f712ae6883f6f5d4a0..8097dddcf5addcc4dfeafbd2d1ea1cee7572d385 100644 --- a/services/screenservice/sourceservice/dscreenmgr/2.0/src/dscreen.cpp +++ b/services/screenservice/sourceservice/dscreenmgr/2.0/src/dscreen.cpp @@ -18,8 +18,12 @@ #include "avcodec_info.h" #include "avcodec_list.h" #include "2.0/include/av_sender_engine_adapter.h" +#include "distributed_hardware_fwk_kit.h" +#include "histreamer_query_tool.h" + #include "dscreen_constants.h" #include "dscreen_errcode.h" +#include "dscreen_fwkkit.h" #include "dscreen_hisysevent.h" #include "dscreen_json_util.h" #include "dscreen_log.h" @@ -29,6 +33,14 @@ namespace OHOS { namespace DistributedHardware { namespace V2_0 { +/* <, codec> */ +static const std::map, std::string> CODECS_MAP = { + {{"HdiCodecAdapter.OMX.rk.video_encoder.hevc", "HdiCodecAdapter.OMX.rk.video_decoder.hevc"}, CODEC_NAME_H265}, + {{"HdiCodecAdapter.OMX.hisi.video.encoder.hevc", "HdiCodecAdapter.OMX.hisi.video.decoder.hevc"}, CODEC_NAME_H265}, + {{"HdiCodecAdapter.OMX.rk.video_encoder.avc", "HdiCodecAdapter.OMX.rk.video_decoder.avc"}, CODEC_NAME_H264}, + {{"HdiCodecAdapter.OMX.hisi.video.encoder.avc", "HdiCodecAdapter.OMX.hisi.video.decoder.avc"}, CODEC_NAME_H264}, +}; + DScreen::DScreen(const std::string &devId, const std::string &dhId, std::shared_ptr dscreenCallback) { @@ -122,7 +134,7 @@ void DScreen::HandleEnable(const std::string ¶m, const std::string &taskId) if (videoParam_ == nullptr) { videoParam_ = std::make_shared(); } - int32_t ret = NegotiateCodecType(attrJson[KEY_CODECTYPE]); + int32_t ret = NegotiateCodecType(attrJson[KEY_HISTREAMER_VIDEO_DECODER]); if (ret != DH_SUCCESS) { DHLOGE("HandleEnable, negotiate codec type failed."); dscreenCallback_->OnRegResult(shared_from_this(), taskId, ERR_DH_SCREEN_SA_ENABLE_FAILED, @@ -437,36 +449,56 @@ int32_t DScreen::SetUp() return senderAdapter_->SetParameter(AVTransTag::ENGINE_READY, OWNER_NAME_D_SCREEN); } -int32_t DScreen::NegotiateCodecType(const std::string &remoteCodecInfoStr) +int32_t DScreen::NegotiateCodecType(const std::string &rmtDecoderStr) { - json remoteCodecArray = json::parse(remoteCodecInfoStr, nullptr, false); - if (remoteCodecArray.is_discarded() || !remoteCodecArray.is_array()) { - DHLOGE("remoteCodecInfoStrjson is invalid."); + DHLOGI("Start NegotiateCodecType, remote decoder: %s", rmtDecoderStr.c_str()); + json rmtDecoderJson = json::parse(rmtDecoderStr, nullptr, false); + if (rmtDecoderJson.is_discarded()) { + DHLOGE("remote Decoder Json is invalid."); return ERR_DH_SCREEN_SA_DSCREEN_NEGOTIATE_CODEC_FAIL; } - std::vector localCodecArray; - std::shared_ptr codecList = Media::AVCodecListFactory::CreateAVCodecList(); - if (codecList == nullptr) { - DHLOGE("codecList is nullptr."); + std::vector rmtVideoDecoders; + FromJson(VIDEO_DECODERS, rmtDecoderJson, rmtVideoDecoders); + + std::shared_ptr dhFwkKit = DScreenFwkKit::GetInstance().GetDHFwkKit(); + if (dhFwkKit == nullptr) { + DHLOGE("Get DhFwkKit return null"); return ERR_DH_SCREEN_SA_DSCREEN_NEGOTIATE_CODEC_FAIL; } - std::vector> caps = codecList->GetVideoEncoderCaps(); - for (const auto &cap : caps) { - if (cap == nullptr) { - continue; - } - std::shared_ptr codecInfo = cap->GetCodecInfo(); - if (codecInfo == nullptr) { - continue; - } - localCodecArray.push_back(codecInfo->GetName()); + std::string localVideoEncodersJsonStr = + dhFwkKit->QueryLocalSysSpec(QueryLocalSysSpecType::HISTREAMER_VIDEO_ENCODER); + if (localVideoEncodersJsonStr.empty()) { + DHLOGE("Query local Codec info failed"); + return ERR_DH_SCREEN_SA_DSCREEN_NEGOTIATE_CODEC_FAIL; + } + DHLOGI("DScreen Negotiate QueryVideoEncoderAbility info: %s", localVideoEncodersJsonStr.c_str()); + + json localVideoEncodersJson = json::parse(localVideoEncodersJsonStr, nullptr, false); + if (localVideoEncodersJson.is_discarded()) { + DHLOGE("localVideoEncodersJson is invalid."); + return ERR_DH_SCREEN_SA_DSCREEN_NEGOTIATE_CODEC_FAIL; } + + std::vector localVideoEncoders; + FromJson(VIDEO_ENCODERS, localVideoEncodersJson, localVideoEncoders); + + return ChooseCodecType(localVideoEncoders, rmtVideoDecoders); +} + +int32_t DScreen::ChooseCodecType(const std::vector &localVideoEncoders, + const std::vector &rmtVideoDecoders) +{ std::vector codecTypeCandidates; - for (const auto &remoteCodecType : remoteCodecArray) { - if (std::find(localCodecArray.begin(), localCodecArray.end(), - remoteCodecType) != localCodecArray.end()) { - codecTypeCandidates.push_back(remoteCodecType); + for (const auto &rmtDec : rmtVideoDecoders) { + for (const auto &locEnc : localVideoEncoders) { + std::pair comb = {locEnc.name, rmtDec.name}; + if (CODECS_MAP.find(comb) != CODECS_MAP.end()) { + std::string codec = CODECS_MAP.at(comb); + DHLOGI("Find match comb, local encoder: %s, remote decoder: %s, codec: %s", + locEnc.name.c_str(), rmtDec.name.c_str(), codec.c_str()); + codecTypeCandidates.push_back(codec); + } } } if (std::find(codecTypeCandidates.begin(), codecTypeCandidates.end(), @@ -477,10 +509,6 @@ int32_t DScreen::NegotiateCodecType(const std::string &remoteCodecInfoStr) CODEC_NAME_H264) != codecTypeCandidates.end()) { videoParam_->SetCodecType(VIDEO_CODEC_TYPE_VIDEO_H264); videoParam_->SetVideoFormat(VIDEO_DATA_FORMAT_NV12); - } else if (std::find(codecTypeCandidates.begin(), codecTypeCandidates.end(), - CODEC_NAME_MPEG4) != codecTypeCandidates.end()) { - videoParam_->SetCodecType(VIDEO_CODEC_TYPE_VIDEO_MPEG4); - videoParam_->SetVideoFormat(VIDEO_DATA_FORMAT_RGBA8888); } else { DHLOGI("codec type not support."); return ERR_DH_SCREEN_SA_DSCREEN_NEGOTIATE_CODEC_FAIL;