1e0e9324cSopenharmony_ci/* 2e0e9324cSopenharmony_ci * Copyright (c) 2023 Shenzhen Kaihong Digital Industry Development Co., Ltd. 3e0e9324cSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4e0e9324cSopenharmony_ci * you may not use this file except in compliance with the License. 5e0e9324cSopenharmony_ci * You may obtain a copy of the License at 6e0e9324cSopenharmony_ci * 7e0e9324cSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8e0e9324cSopenharmony_ci * 9e0e9324cSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10e0e9324cSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11e0e9324cSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12e0e9324cSopenharmony_ci * See the License for the specific language governing permissions and 13e0e9324cSopenharmony_ci * limitations under the License. 14e0e9324cSopenharmony_ci */ 15e0e9324cSopenharmony_ci 16e0e9324cSopenharmony_ci#include "wfd_message.h" 17e0e9324cSopenharmony_ci#include <iomanip> 18e0e9324cSopenharmony_ci#include <iostream> 19e0e9324cSopenharmony_ci#include <sstream> 20e0e9324cSopenharmony_ci#include <cstdio> 21e0e9324cSopenharmony_ci#include "common/sharing_log.h" 22e0e9324cSopenharmony_ci 23e0e9324cSopenharmony_cinamespace OHOS { 24e0e9324cSopenharmony_cinamespace Sharing { 25e0e9324cSopenharmony_ciconstexpr int32_t BIT_OFFSET_TWO = 2; 26e0e9324cSopenharmony_ciconstexpr int32_t BIT_OFFSET_THREE = 3; 27e0e9324cSopenharmony_ciconstexpr int32_t BIT_OFFSET_EIGHT = 8; 28e0e9324cSopenharmony_ci 29e0e9324cSopenharmony_ciWfdRtspM1Response::WfdRtspM1Response(int32_t cseq, int32_t status) : RtspResponseOptions(cseq, status) 30e0e9324cSopenharmony_ci{ 31e0e9324cSopenharmony_ci std::stringstream ss; 32e0e9324cSopenharmony_ci ss << RTSP_METHOD_WFD << "," << RTSP_SP << RTSP_METHOD_SET_PARAMETER << "," << RTSP_SP << RTSP_METHOD_GET_PARAMETER; 33e0e9324cSopenharmony_ci SetPublicItems(ss.str()); 34e0e9324cSopenharmony_ci} 35e0e9324cSopenharmony_ci 36e0e9324cSopenharmony_ciRtspError WfdRtspM3Response::Parse(const std::string &response) 37e0e9324cSopenharmony_ci{ 38e0e9324cSopenharmony_ci auto res = RtspResponse::Parse(response); 39e0e9324cSopenharmony_ci if (res.code != RtspErrorType::OK) { 40e0e9324cSopenharmony_ci return res; 41e0e9324cSopenharmony_ci } 42e0e9324cSopenharmony_ci 43e0e9324cSopenharmony_ci RtspCommon::SplitParameter(body_, params_); 44e0e9324cSopenharmony_ci return {}; 45e0e9324cSopenharmony_ci} 46e0e9324cSopenharmony_ci 47e0e9324cSopenharmony_cistd::string WfdRtspM3Response::Stringify() 48e0e9324cSopenharmony_ci{ 49e0e9324cSopenharmony_ci std::stringstream body; 50e0e9324cSopenharmony_ci std::stringstream ss; 51e0e9324cSopenharmony_ci 52e0e9324cSopenharmony_ci for (auto ¶m : params_) { 53e0e9324cSopenharmony_ci body << param.first << ":" << RTSP_SP << param.second << RTSP_CRLF; 54e0e9324cSopenharmony_ci } 55e0e9324cSopenharmony_ci 56e0e9324cSopenharmony_ci ss << RTSP_TOKEN_CONTENT_TYPE << ":" << RTSP_SP << "text/parameters" << RTSP_CRLF; 57e0e9324cSopenharmony_ci ss << RTSP_TOKEN_CONTENT_LENGTH << ":" << RTSP_SP << body.str().length(); 58e0e9324cSopenharmony_ci 59e0e9324cSopenharmony_ci ClearCustomHeader(); 60e0e9324cSopenharmony_ci AddCustomHeader(ss.str()); 61e0e9324cSopenharmony_ci 62e0e9324cSopenharmony_ci if (body.str().empty()) { 63e0e9324cSopenharmony_ci return RtspResponse::Stringify(); 64e0e9324cSopenharmony_ci } 65e0e9324cSopenharmony_ci 66e0e9324cSopenharmony_ci return RtspResponse::Stringify() + body.str(); 67e0e9324cSopenharmony_ci} 68e0e9324cSopenharmony_ci 69e0e9324cSopenharmony_civoid WfdRtspM3Response::SetVideoFormats(VideoFormat format) 70e0e9324cSopenharmony_ci{ 71e0e9324cSopenharmony_ci std::stringstream ss; 72e0e9324cSopenharmony_ci std::stringstream sinkVideoList; 73e0e9324cSopenharmony_ci 74e0e9324cSopenharmony_ci uint8_t native = 0; 75e0e9324cSopenharmony_ci uint8_t h264Profile = (1 << (uint8_t)WfdH264Profile::PROFILE_CHP); 76e0e9324cSopenharmony_ci uint8_t h264Level = (1 << (uint8_t)WfdH264Level::LEVEL_42); 77e0e9324cSopenharmony_ci uint32_t ceaResolutionIndex = 0; 78e0e9324cSopenharmony_ci uint32_t vesaResolutionIndex = 0; 79e0e9324cSopenharmony_ci uint32_t hhResolutionIndex = 0; 80e0e9324cSopenharmony_ci 81e0e9324cSopenharmony_ci switch (format) { 82e0e9324cSopenharmony_ci case VIDEO_1920X1080_30: 83e0e9324cSopenharmony_ci native = (uint8_t)WfdResolutionType::RESOLUTION_CEA | (CEA_1920_1080_P30 << BIT_OFFSET_THREE); 84e0e9324cSopenharmony_ci ceaResolutionIndex = (1 << CEA_1920_1080_P30); 85e0e9324cSopenharmony_ci break; 86e0e9324cSopenharmony_ci case VIDEO_1920X1080_25: 87e0e9324cSopenharmony_ci native = (uint8_t)WfdResolutionType::RESOLUTION_CEA | (CEA_1920_1080_P25 << BIT_OFFSET_THREE); 88e0e9324cSopenharmony_ci ceaResolutionIndex = (1 << CEA_1920_1080_P25); 89e0e9324cSopenharmony_ci break; 90e0e9324cSopenharmony_ci case VIDEO_1280X720_30: 91e0e9324cSopenharmony_ci native = (uint8_t)WfdResolutionType::RESOLUTION_CEA | (CEA_1280_720_P30 << BIT_OFFSET_THREE); 92e0e9324cSopenharmony_ci ceaResolutionIndex = (1 << CEA_1280_720_P30); 93e0e9324cSopenharmony_ci break; 94e0e9324cSopenharmony_ci case VIDEO_1280X720_25: 95e0e9324cSopenharmony_ci native = (uint8_t)WfdResolutionType::RESOLUTION_CEA | (CEA_1280_720_P25 << BIT_OFFSET_THREE); 96e0e9324cSopenharmony_ci ceaResolutionIndex = (1 << CEA_1280_720_P25); 97e0e9324cSopenharmony_ci break; 98e0e9324cSopenharmony_ci case VIDEO_640X480_60: 99e0e9324cSopenharmony_ci default: 100e0e9324cSopenharmony_ci native = 101e0e9324cSopenharmony_ci (uint8_t)WfdResolutionType::RESOLUTION_CEA | (WfdCeaResolution::CEA_640_480_P60 << BIT_OFFSET_THREE); 102e0e9324cSopenharmony_ci ceaResolutionIndex = (1 << CEA_640_480_P60); 103e0e9324cSopenharmony_ci break; 104e0e9324cSopenharmony_ci } 105e0e9324cSopenharmony_ci 106e0e9324cSopenharmony_ci ss << std::setfill('0') << std::setw(BIT_OFFSET_TWO) << std::hex << (int32_t)native << RTSP_SP << "00" << RTSP_SP; 107e0e9324cSopenharmony_ci ss << std::setfill('0') << std::setw(BIT_OFFSET_TWO) << std::hex << (int32_t)h264Profile << RTSP_SP; 108e0e9324cSopenharmony_ci ss << std::setfill('0') << std::setw(BIT_OFFSET_TWO) << std::hex << (int32_t)h264Level << RTSP_SP; 109e0e9324cSopenharmony_ci ss << std::setfill('0') << std::setw(BIT_OFFSET_EIGHT) << std::hex << ceaResolutionIndex << RTSP_SP; 110e0e9324cSopenharmony_ci ss << std::setfill('0') << std::setw(BIT_OFFSET_EIGHT) << std::hex << vesaResolutionIndex << RTSP_SP; 111e0e9324cSopenharmony_ci ss << std::setfill('0') << std::setw(BIT_OFFSET_EIGHT) << std::hex << hhResolutionIndex << RTSP_SP; 112e0e9324cSopenharmony_ci 113e0e9324cSopenharmony_ci ss << "00 0000 0000 00 none none"; 114e0e9324cSopenharmony_ci 115e0e9324cSopenharmony_ci params_.emplace_back(WFD_PARAM_VIDEO_FORMATS, ss.str()); 116e0e9324cSopenharmony_ci} 117e0e9324cSopenharmony_ci 118e0e9324cSopenharmony_civoid WfdRtspM3Response::SetAudioCodecs(AudioFormat format) 119e0e9324cSopenharmony_ci{ 120e0e9324cSopenharmony_ci std::stringstream ss; 121e0e9324cSopenharmony_ci switch (format) { 122e0e9324cSopenharmony_ci case AUDIO_44100_8_2: 123e0e9324cSopenharmony_ci ss << "LPCM" << RTSP_SP << "00000001 00"; 124e0e9324cSopenharmony_ci break; 125e0e9324cSopenharmony_ci case AUDIO_44100_16_2: 126e0e9324cSopenharmony_ci ss << "LPCM" << RTSP_SP << "00000002 00"; 127e0e9324cSopenharmony_ci break; 128e0e9324cSopenharmony_ci case AUDIO_48000_16_2: 129e0e9324cSopenharmony_ci ss << "AAC" << RTSP_SP << "00000001 00"; 130e0e9324cSopenharmony_ci break; 131e0e9324cSopenharmony_ci default: 132e0e9324cSopenharmony_ci ss << "AAC" << RTSP_SP << "00000001 00"; 133e0e9324cSopenharmony_ci break; 134e0e9324cSopenharmony_ci } 135e0e9324cSopenharmony_ci 136e0e9324cSopenharmony_ci params_.emplace_back(WFD_PARAM_AUDIO_CODECS, ss.str()); 137e0e9324cSopenharmony_ci} 138e0e9324cSopenharmony_ci 139e0e9324cSopenharmony_civoid WfdRtspM3Response::SetClientRtpPorts(int32_t port) 140e0e9324cSopenharmony_ci{ 141e0e9324cSopenharmony_ci std::stringstream ss; 142e0e9324cSopenharmony_ci ss << "RTP/AVP/UDP;unicast" << RTSP_SP << port << RTSP_SP << 0 << RTSP_SP << "mode=play"; 143e0e9324cSopenharmony_ci params_.emplace_back(WFD_PARAM_RTP_PORTS, ss.str()); 144e0e9324cSopenharmony_ci} 145e0e9324cSopenharmony_ci 146e0e9324cSopenharmony_civoid WfdRtspM3Response::SetContentProtection(const std::string &value) 147e0e9324cSopenharmony_ci{ 148e0e9324cSopenharmony_ci params_.emplace_back(WFD_PARAM_CONTENT_PROTECTION, value); 149e0e9324cSopenharmony_ci} 150e0e9324cSopenharmony_ci 151e0e9324cSopenharmony_civoid WfdRtspM3Response::SetCoupledSink(const std::string &value) 152e0e9324cSopenharmony_ci{ 153e0e9324cSopenharmony_ci params_.emplace_back(WFD_PARAM_COUPLED_SINK, value); 154e0e9324cSopenharmony_ci} 155e0e9324cSopenharmony_ci 156e0e9324cSopenharmony_civoid WfdRtspM3Response::SetUibcCapability(const std::string &value) 157e0e9324cSopenharmony_ci{ 158e0e9324cSopenharmony_ci params_.emplace_back(WFD_PARAM_UIBC_CAPABILITY, value); 159e0e9324cSopenharmony_ci} 160e0e9324cSopenharmony_ci 161e0e9324cSopenharmony_civoid WfdRtspM3Response::SetStandbyResumeCapability(const std::string &value) 162e0e9324cSopenharmony_ci{ 163e0e9324cSopenharmony_ci params_.emplace_back(WFD_PARAM_UIBC_CAPABILITY, value); 164e0e9324cSopenharmony_ci} 165e0e9324cSopenharmony_ci 166e0e9324cSopenharmony_civoid WfdRtspM3Response::SetCustomParam(const std::string &key, const std::string &value) 167e0e9324cSopenharmony_ci{ 168e0e9324cSopenharmony_ci params_.emplace_back(key, value); 169e0e9324cSopenharmony_ci} 170e0e9324cSopenharmony_ci 171e0e9324cSopenharmony_ciint32_t WfdRtspM3Response::GetClientRtpPorts() 172e0e9324cSopenharmony_ci{ 173e0e9324cSopenharmony_ci int32_t port0 = -1; 174e0e9324cSopenharmony_ci int32_t port1 = -1; 175e0e9324cSopenharmony_ci std::string profile = "RTP/AVP/UDP;unicast"; 176e0e9324cSopenharmony_ci std::string mode = "mode=play"; 177e0e9324cSopenharmony_ci std::string value = GetCustomParam(WFD_PARAM_RTP_PORTS); 178e0e9324cSopenharmony_ci std::stringstream ss(value); 179e0e9324cSopenharmony_ci ss >> profile >> port0 >> port1 >> mode; 180e0e9324cSopenharmony_ci return port0; 181e0e9324cSopenharmony_ci} 182e0e9324cSopenharmony_ci 183e0e9324cSopenharmony_cistd::string WfdRtspM3Response::GetUibcCapability() 184e0e9324cSopenharmony_ci{ 185e0e9324cSopenharmony_ci std::string value = GetCustomParam(WFD_PARAM_UIBC_CAPABILITY); 186e0e9324cSopenharmony_ci return value; 187e0e9324cSopenharmony_ci} 188e0e9324cSopenharmony_ci 189e0e9324cSopenharmony_ciAudioFormat WfdRtspM3Response::GetAudioCodecs(WfdAudioCodec &codec) 190e0e9324cSopenharmony_ci{ 191e0e9324cSopenharmony_ci std::string value = GetCustomParam(WFD_PARAM_AUDIO_CODECS); 192e0e9324cSopenharmony_ci int32_t audioFormat0 = -1; 193e0e9324cSopenharmony_ci int32_t audioFormat1 = -1; 194e0e9324cSopenharmony_ci std::string format; 195e0e9324cSopenharmony_ci auto audioCaps = RtspCommon::Split(value, ", "); 196e0e9324cSopenharmony_ci for (size_t i = 0; i < audioCaps.size(); i++) { 197e0e9324cSopenharmony_ci std::string audioCap = audioCaps[i]; 198e0e9324cSopenharmony_ci std::stringstream ss(audioCap); 199e0e9324cSopenharmony_ci ss >> format >> audioFormat0 >> audioFormat1; 200e0e9324cSopenharmony_ci if (format == "LPCM") { // LPCM 201e0e9324cSopenharmony_ci if (codec.codecId != CODEC_AAC && audioFormat0 > 1) { 202e0e9324cSopenharmony_ci codec.codecId = CODEC_PCM; 203e0e9324cSopenharmony_ci codec.format = AUDIO_48000_16_2; 204e0e9324cSopenharmony_ci } 205e0e9324cSopenharmony_ci } else if (format == "AAC") { // AAC 206e0e9324cSopenharmony_ci codec.codecId = CODEC_AAC; 207e0e9324cSopenharmony_ci codec.format = AUDIO_48000_16_2; 208e0e9324cSopenharmony_ci } else if (format == "AC3") { // AC3 209e0e9324cSopenharmony_ci if (audioFormat0 == 1) { 210e0e9324cSopenharmony_ci } 211e0e9324cSopenharmony_ci continue; 212e0e9324cSopenharmony_ci } 213e0e9324cSopenharmony_ci } 214e0e9324cSopenharmony_ci 215e0e9324cSopenharmony_ci return codec.format; 216e0e9324cSopenharmony_ci} 217e0e9324cSopenharmony_ci 218e0e9324cSopenharmony_cistd::string WfdRtspM3Response::GetCoupledSink() 219e0e9324cSopenharmony_ci{ 220e0e9324cSopenharmony_ci std::string value = GetCustomParam(WFD_PARAM_COUPLED_SINK); 221e0e9324cSopenharmony_ci return value; 222e0e9324cSopenharmony_ci} 223e0e9324cSopenharmony_ci 224e0e9324cSopenharmony_cistd::string WfdRtspM3Response::GetContentProtection() 225e0e9324cSopenharmony_ci{ 226e0e9324cSopenharmony_ci std::string value = GetCustomParam(WFD_PARAM_CONTENT_PROTECTION); 227e0e9324cSopenharmony_ci return value; 228e0e9324cSopenharmony_ci} 229e0e9324cSopenharmony_ci 230e0e9324cSopenharmony_ciVideoFormat WfdRtspM3Response::GetVideoFormatsByCea(int index) 231e0e9324cSopenharmony_ci{ 232e0e9324cSopenharmony_ci WfdCeaResolution res = static_cast<WfdCeaResolution>(index); 233e0e9324cSopenharmony_ci switch (res) { 234e0e9324cSopenharmony_ci case CEA_640_480_P60: 235e0e9324cSopenharmony_ci return VIDEO_640X480_60; 236e0e9324cSopenharmony_ci case CEA_1280_720_P30: 237e0e9324cSopenharmony_ci return VIDEO_1280X720_30; 238e0e9324cSopenharmony_ci case CEA_1280_720_P60: 239e0e9324cSopenharmony_ci return VIDEO_1280X720_60; 240e0e9324cSopenharmony_ci case CEA_1920_1080_P25: 241e0e9324cSopenharmony_ci return VIDEO_1920X1080_25; 242e0e9324cSopenharmony_ci case CEA_1920_1080_P30: 243e0e9324cSopenharmony_ci return VIDEO_1920X1080_30; 244e0e9324cSopenharmony_ci case CEA_1920_1080_P60: 245e0e9324cSopenharmony_ci return VIDEO_1920X1080_60; 246e0e9324cSopenharmony_ci default: 247e0e9324cSopenharmony_ci return VIDEO_640X480_60; 248e0e9324cSopenharmony_ci } 249e0e9324cSopenharmony_ci} 250e0e9324cSopenharmony_ci 251e0e9324cSopenharmony_ciVideoFormat WfdRtspM3Response::GetVideoFormats() 252e0e9324cSopenharmony_ci{ 253e0e9324cSopenharmony_ci // wfd_video_formats: 254e0e9324cSopenharmony_ci // 1 byte "native" 255e0e9324cSopenharmony_ci // 1 byte "preferred-display-mode-supported" 0 or 1 256e0e9324cSopenharmony_ci // one or more avc codec structures 257e0e9324cSopenharmony_ci // 1 byte profile 258e0e9324cSopenharmony_ci // 1 byte level 259e0e9324cSopenharmony_ci // 4 byte CEA mask 260e0e9324cSopenharmony_ci // 4 byte VESA mask 261e0e9324cSopenharmony_ci // 4 byte HH mask 262e0e9324cSopenharmony_ci // 1 byte latency 263e0e9324cSopenharmony_ci // 2 byte min-slice-slice 264e0e9324cSopenharmony_ci // 2 byte slice-enc-params 265e0e9324cSopenharmony_ci // 1 byte framerate-control-support 266e0e9324cSopenharmony_ci // max-hres (none or 2 byte) 267e0e9324cSopenharmony_ci // max-vres (none or 2 byte) 268e0e9324cSopenharmony_ci /** 269e0e9324cSopenharmony_ci * native: 2*2HEXDIG 270e0e9324cSopenharmony_ci * preferred-display-mode-supported: 2*2HEXDIG; 0-not supported, 1-supported, 2-255 reserved 271e0e9324cSopenharmony_ci * profile: 2*2HEXDIG, only one bit set 272e0e9324cSopenharmony_ci * level: 2*2HEXDIG, only one bit set 273e0e9324cSopenharmony_ci * CEA-Support: 8*8HEXDIG, 0-ignore 274e0e9324cSopenharmony_ci * VESA-Support:8*8HEXDIG, 0-ignore 275e0e9324cSopenharmony_ci * HH-Support: 8*8HEXDIG, 0-ignore 276e0e9324cSopenharmony_ci * latency: 2*2HEXDIG, decoder latency in units of 5 msecs 277e0e9324cSopenharmony_ci * min-slice-size: 4*4HEXDIG, number of macroblocks 278e0e9324cSopenharmony_ci * slice-enc-params: 4*4HEXDIG, 279e0e9324cSopenharmony_ci * frame-rate-control-support: 4*4HEXDIG 280e0e9324cSopenharmony_ci * max-hres: 4*4HEXDIG, "none" if preferred-display-mode-supported is 0 281e0e9324cSopenharmony_ci * max-vres: 4*4HEXDIG, "none" if preferred-display-mode-supported is 0 282e0e9324cSopenharmony_ci **/ 283e0e9324cSopenharmony_ci std::string value = GetCustomParam(WFD_PARAM_VIDEO_FORMATS); 284e0e9324cSopenharmony_ci if (value.size() < MINIMAL_VIDEO_FORMAT_SIZE) { 285e0e9324cSopenharmony_ci return VIDEO_640X480_60; 286e0e9324cSopenharmony_ci } 287e0e9324cSopenharmony_ci 288e0e9324cSopenharmony_ci std::string head = value.substr(0, 5); // 5: fix offset 289e0e9324cSopenharmony_ci uint16_t native = 0; 290e0e9324cSopenharmony_ci uint16_t preferredDisplayMode = 0; 291e0e9324cSopenharmony_ci int index = 0; 292e0e9324cSopenharmony_ci std::string temp = ""; 293e0e9324cSopenharmony_ci bool run = true; 294e0e9324cSopenharmony_ci std::stringstream ss(head); 295e0e9324cSopenharmony_ci ss >> std::hex >> native >> std::hex >> preferredDisplayMode; 296e0e9324cSopenharmony_ci value = value.substr(5); // 5: fix offset 297e0e9324cSopenharmony_ci 298e0e9324cSopenharmony_ci while (run) { 299e0e9324cSopenharmony_ci auto nPos = value.find_first_of(",", index + 1); 300e0e9324cSopenharmony_ci if (nPos != std::string::npos) { 301e0e9324cSopenharmony_ci index = nPos; 302e0e9324cSopenharmony_ci temp = value.substr(0, index); 303e0e9324cSopenharmony_ci } else { 304e0e9324cSopenharmony_ci temp = value.substr(index + 1); 305e0e9324cSopenharmony_ci run = false; 306e0e9324cSopenharmony_ci } 307e0e9324cSopenharmony_ci std::stringstream sss(temp); 308e0e9324cSopenharmony_ci WfdVideoFormatsInfo wfdVideoFormatsInfo; 309e0e9324cSopenharmony_ci wfdVideoFormatsInfo.native = native; 310e0e9324cSopenharmony_ci wfdVideoFormatsInfo.preferredDisplayMode = preferredDisplayMode; 311e0e9324cSopenharmony_ci sss >> std::hex >> wfdVideoFormatsInfo.profile >> std::hex >> wfdVideoFormatsInfo.level >> std::hex >> 312e0e9324cSopenharmony_ci wfdVideoFormatsInfo.ceaMask >> std::hex >> wfdVideoFormatsInfo.veaMask >> std::hex >> 313e0e9324cSopenharmony_ci wfdVideoFormatsInfo.hhMask >> std::hex >> wfdVideoFormatsInfo.latency >> std::hex >> 314e0e9324cSopenharmony_ci wfdVideoFormatsInfo.minSlice >> std::hex >> wfdVideoFormatsInfo.sliceEncParam >> std::hex >> 315e0e9324cSopenharmony_ci wfdVideoFormatsInfo.frameRateCtlSupport; 316e0e9324cSopenharmony_ci vWfdVideoFormatsInfo_.push_back(wfdVideoFormatsInfo); 317e0e9324cSopenharmony_ci } 318e0e9324cSopenharmony_ci 319e0e9324cSopenharmony_ci uint8_t tableSelection = vWfdVideoFormatsInfo_[0].native & 0x7; 320e0e9324cSopenharmony_ci index = vWfdVideoFormatsInfo_[0].native >> BIT_OFFSET_THREE; 321e0e9324cSopenharmony_ci switch (tableSelection) { 322e0e9324cSopenharmony_ci case 0: 323e0e9324cSopenharmony_ci return GetVideoFormatsByCea(index); 324e0e9324cSopenharmony_ci default: 325e0e9324cSopenharmony_ci return VIDEO_640X480_60; 326e0e9324cSopenharmony_ci } 327e0e9324cSopenharmony_ci return VIDEO_640X480_60; 328e0e9324cSopenharmony_ci} 329e0e9324cSopenharmony_ci 330e0e9324cSopenharmony_cistd::string WfdRtspM3Response::GetStandbyResumeCapability() 331e0e9324cSopenharmony_ci{ 332e0e9324cSopenharmony_ci std::string value = GetCustomParam(WFD_PARAM_STANDBY_RESUME); 333e0e9324cSopenharmony_ci return value; 334e0e9324cSopenharmony_ci} 335e0e9324cSopenharmony_ci 336e0e9324cSopenharmony_cistd::string WfdRtspM3Response::GetCustomParam(const std::string &key) 337e0e9324cSopenharmony_ci{ 338e0e9324cSopenharmony_ci auto it = std::find_if(params_.begin(), params_.end(), 339e0e9324cSopenharmony_ci [=](std::pair<std::string, std::string> value) { return value.first == key; }); 340e0e9324cSopenharmony_ci if (it != params_.end()) { 341e0e9324cSopenharmony_ci return it->second; 342e0e9324cSopenharmony_ci } 343e0e9324cSopenharmony_ci 344e0e9324cSopenharmony_ci return ""; 345e0e9324cSopenharmony_ci} 346e0e9324cSopenharmony_ci 347e0e9324cSopenharmony_civoid WfdRtspM4Request::SetClientRtpPorts(int32_t port) 348e0e9324cSopenharmony_ci{ 349e0e9324cSopenharmony_ci std::stringstream ss; 350e0e9324cSopenharmony_ci ss << WFD_PARAM_RTP_PORTS << ":" << RTSP_SP << "RTP/AVP/UDP;unicast" << RTSP_SP << port << RTSP_SP << 0 << RTSP_SP 351e0e9324cSopenharmony_ci << "mode=play"; 352e0e9324cSopenharmony_ci AddBodyItem(ss.str()); 353e0e9324cSopenharmony_ci} 354e0e9324cSopenharmony_ci 355e0e9324cSopenharmony_civoid WfdRtspM4Request::SetAudioCodecs(WfdAudioCodec &codec) 356e0e9324cSopenharmony_ci{ 357e0e9324cSopenharmony_ci std::stringstream ss; 358e0e9324cSopenharmony_ci ss << WFD_PARAM_AUDIO_CODECS << ":" << RTSP_SP; 359e0e9324cSopenharmony_ci 360e0e9324cSopenharmony_ci switch (codec.codecId) { 361e0e9324cSopenharmony_ci case CODEC_PCM: 362e0e9324cSopenharmony_ci ss << "LPCM" << RTSP_SP << "00000002 00"; 363e0e9324cSopenharmony_ci break; 364e0e9324cSopenharmony_ci case CODEC_AAC: 365e0e9324cSopenharmony_ci ss << "AAC" << RTSP_SP << "00000001 00"; 366e0e9324cSopenharmony_ci break; 367e0e9324cSopenharmony_ci default: 368e0e9324cSopenharmony_ci ss << "AAC" << RTSP_SP << "00000001 00"; 369e0e9324cSopenharmony_ci break; 370e0e9324cSopenharmony_ci } 371e0e9324cSopenharmony_ci 372e0e9324cSopenharmony_ci AddBodyItem(ss.str()); 373e0e9324cSopenharmony_ci} 374e0e9324cSopenharmony_ci 375e0e9324cSopenharmony_civoid WfdRtspM4Request::SetPresentationUrl(const std::string &ip) 376e0e9324cSopenharmony_ci{ 377e0e9324cSopenharmony_ci std::stringstream ss; 378e0e9324cSopenharmony_ci ss << WFD_PARAM_PRESENTATION_URL << ":" << RTSP_SP << "rtsp://" << ip.c_str() << "/wfd1.0/streamid=0 none"; 379e0e9324cSopenharmony_ci AddBodyItem(ss.str()); 380e0e9324cSopenharmony_ci} 381e0e9324cSopenharmony_ci 382e0e9324cSopenharmony_civoid WfdRtspM4Request::SetVideoFormats(const WfdVideoFormatsInfo &wfdVideoFormatsInfo, VideoFormat format) 383e0e9324cSopenharmony_ci{ 384e0e9324cSopenharmony_ci std::stringstream ss; 385e0e9324cSopenharmony_ci uint32_t native = wfdVideoFormatsInfo.native; 386e0e9324cSopenharmony_ci uint32_t h264Profile = wfdVideoFormatsInfo.profile; 387e0e9324cSopenharmony_ci uint32_t h264Level = wfdVideoFormatsInfo.level; 388e0e9324cSopenharmony_ci uint32_t ceaResolutionIndex = 0; 389e0e9324cSopenharmony_ci uint32_t vesaResolutionIndex = 0; 390e0e9324cSopenharmony_ci uint32_t hhResolutionIndex = 0; 391e0e9324cSopenharmony_ci (void)ceaResolutionIndex; 392e0e9324cSopenharmony_ci (void)vesaResolutionIndex; 393e0e9324cSopenharmony_ci (void)hhResolutionIndex; 394e0e9324cSopenharmony_ci (void)h264Profile; 395e0e9324cSopenharmony_ci (void)h264Level; 396e0e9324cSopenharmony_ci 397e0e9324cSopenharmony_ci switch (format) { 398e0e9324cSopenharmony_ci case VIDEO_1920X1080_60: 399e0e9324cSopenharmony_ci case VIDEO_1920X1080_30: 400e0e9324cSopenharmony_ci native = (uint8_t)WfdResolutionType::RESOLUTION_CEA | (CEA_1920_1080_P30 << BIT_OFFSET_THREE); 401e0e9324cSopenharmony_ci ceaResolutionIndex = (1 << CEA_1920_1080_P30); 402e0e9324cSopenharmony_ci break; 403e0e9324cSopenharmony_ci case VIDEO_1920X1080_25: 404e0e9324cSopenharmony_ci native = (uint8_t)WfdResolutionType::RESOLUTION_CEA | (CEA_1920_1080_P25 << BIT_OFFSET_THREE); 405e0e9324cSopenharmony_ci ceaResolutionIndex = (1 << CEA_1920_1080_P25); 406e0e9324cSopenharmony_ci break; 407e0e9324cSopenharmony_ci case VIDEO_1280X720_30: 408e0e9324cSopenharmony_ci native = (uint8_t)WfdResolutionType::RESOLUTION_CEA | (CEA_1280_720_P30 << BIT_OFFSET_THREE); 409e0e9324cSopenharmony_ci ceaResolutionIndex = (1 << CEA_1280_720_P30); 410e0e9324cSopenharmony_ci break; 411e0e9324cSopenharmony_ci case VIDEO_1280X720_25: 412e0e9324cSopenharmony_ci native = (uint8_t)WfdResolutionType::RESOLUTION_CEA | (CEA_1280_720_P25 << BIT_OFFSET_THREE); 413e0e9324cSopenharmony_ci ceaResolutionIndex = (1 << CEA_1280_720_P25); 414e0e9324cSopenharmony_ci break; 415e0e9324cSopenharmony_ci case VIDEO_640X480_60: 416e0e9324cSopenharmony_ci default: 417e0e9324cSopenharmony_ci native = 418e0e9324cSopenharmony_ci (uint8_t)WfdResolutionType::RESOLUTION_CEA | (WfdCeaResolution::CEA_640_480_P60 << BIT_OFFSET_THREE); 419e0e9324cSopenharmony_ci ceaResolutionIndex = (1 << CEA_640_480_P60); 420e0e9324cSopenharmony_ci break; 421e0e9324cSopenharmony_ci } 422e0e9324cSopenharmony_ci 423e0e9324cSopenharmony_ci ss << WFD_PARAM_VIDEO_FORMATS << ":" << RTSP_SP; 424e0e9324cSopenharmony_ci ss << std::setfill('0') << std::setw(BIT_OFFSET_TWO) << std::hex << native << RTSP_SP << "00" << RTSP_SP; 425e0e9324cSopenharmony_ci ss << std::setfill('0') << std::setw(BIT_OFFSET_TWO) << std::hex << h264Profile << RTSP_SP; 426e0e9324cSopenharmony_ci ss << std::setfill('0') << std::setw(BIT_OFFSET_TWO) << std::hex << h264Level << RTSP_SP; 427e0e9324cSopenharmony_ci ss << std::setfill('0') << std::setw(BIT_OFFSET_EIGHT) << std::hex << ceaResolutionIndex << RTSP_SP; 428e0e9324cSopenharmony_ci ss << std::setfill('0') << std::setw(BIT_OFFSET_EIGHT) << std::hex << vesaResolutionIndex << RTSP_SP; 429e0e9324cSopenharmony_ci ss << std::setfill('0') << std::setw(BIT_OFFSET_EIGHT) << std::hex << hhResolutionIndex << RTSP_SP; 430e0e9324cSopenharmony_ci ss << "00 0000 0000 00 none none"; 431e0e9324cSopenharmony_ci AddBodyItem(ss.str()); 432e0e9324cSopenharmony_ci} 433e0e9324cSopenharmony_ci 434e0e9324cSopenharmony_ciRtspError WfdRtspM4Request::Parse(const std::string &request) 435e0e9324cSopenharmony_ci{ 436e0e9324cSopenharmony_ci auto res = RtspRequest::Parse(request); 437e0e9324cSopenharmony_ci if (res.code != RtspErrorType::OK) { 438e0e9324cSopenharmony_ci return res; 439e0e9324cSopenharmony_ci } 440e0e9324cSopenharmony_ci 441e0e9324cSopenharmony_ci RtspCommon::SplitParameter(body_, params_); 442e0e9324cSopenharmony_ci return {}; 443e0e9324cSopenharmony_ci} 444e0e9324cSopenharmony_ci 445e0e9324cSopenharmony_cistd::string WfdRtspM4Request::GetParameterValue(const std::string ¶m) 446e0e9324cSopenharmony_ci{ 447e0e9324cSopenharmony_ci auto it = std::find_if(params_.begin(), params_.end(), 448e0e9324cSopenharmony_ci [=](std::pair<std::string, std::string> value) { return value.first == param; }); 449e0e9324cSopenharmony_ci if (it != params_.end()) { 450e0e9324cSopenharmony_ci return it->second; 451e0e9324cSopenharmony_ci } 452e0e9324cSopenharmony_ci 453e0e9324cSopenharmony_ci return ""; 454e0e9324cSopenharmony_ci} 455e0e9324cSopenharmony_ci 456e0e9324cSopenharmony_cistd::string WfdRtspM4Request::GetPresentationUrl() 457e0e9324cSopenharmony_ci{ 458e0e9324cSopenharmony_ci std::string urls = GetParameterValue(WFD_PARAM_PRESENTATION_URL); 459e0e9324cSopenharmony_ci if (urls.empty()) { 460e0e9324cSopenharmony_ci return ""; 461e0e9324cSopenharmony_ci } 462e0e9324cSopenharmony_ci 463e0e9324cSopenharmony_ci auto urlVec = RtspCommon::Split(urls, " "); 464e0e9324cSopenharmony_ci if (!urlVec.empty()) { 465e0e9324cSopenharmony_ci return urlVec[0]; 466e0e9324cSopenharmony_ci } 467e0e9324cSopenharmony_ci 468e0e9324cSopenharmony_ci return ""; 469e0e9324cSopenharmony_ci} 470e0e9324cSopenharmony_ci 471e0e9324cSopenharmony_ciint32_t WfdRtspM4Request::GetRtpPort() 472e0e9324cSopenharmony_ci{ 473e0e9324cSopenharmony_ci auto ports = GetParameterValue(WFD_PARAM_RTP_PORTS); 474e0e9324cSopenharmony_ci auto resVec = RtspCommon::Split(ports, " "); 475e0e9324cSopenharmony_ci if (resVec.size() > 2) { // 2: fix offset 476e0e9324cSopenharmony_ci return atoi(resVec[1].c_str()); 477e0e9324cSopenharmony_ci } 478e0e9324cSopenharmony_ci 479e0e9324cSopenharmony_ci return 0; 480e0e9324cSopenharmony_ci} 481e0e9324cSopenharmony_ci 482e0e9324cSopenharmony_civoid WfdRtspM5Request::SetTriggerMethod(const std::string &method) 483e0e9324cSopenharmony_ci{ 484e0e9324cSopenharmony_ci std::stringstream ss; 485e0e9324cSopenharmony_ci ss << WFD_PARAM_TRIGGER << ":" << RTSP_SP << method; 486e0e9324cSopenharmony_ci 487e0e9324cSopenharmony_ci body_.emplace_back(ss.str()); 488e0e9324cSopenharmony_ci} 489e0e9324cSopenharmony_ci 490e0e9324cSopenharmony_cistd::string WfdRtspM5Request::GetTriggerMethod() 491e0e9324cSopenharmony_ci{ 492e0e9324cSopenharmony_ci std::list<std::pair<std::string, std::string>> params; 493e0e9324cSopenharmony_ci RtspCommon::SplitParameter(body_, params); 494e0e9324cSopenharmony_ci 495e0e9324cSopenharmony_ci auto it = std::find_if(params.begin(), params.end(), 496e0e9324cSopenharmony_ci [](std::pair<std::string, std::string> value) { return value.first == WFD_PARAM_TRIGGER; }); 497e0e9324cSopenharmony_ci if (it != params.end()) { 498e0e9324cSopenharmony_ci return it->second; 499e0e9324cSopenharmony_ci } 500e0e9324cSopenharmony_ci 501e0e9324cSopenharmony_ci return {}; 502e0e9324cSopenharmony_ci} 503e0e9324cSopenharmony_ci 504e0e9324cSopenharmony_ciint32_t WfdRtspM6Response::GetClientPort() 505e0e9324cSopenharmony_ci{ 506e0e9324cSopenharmony_ci auto transport = GetToken(RTSP_TOKEN_TRANSPORT); 507e0e9324cSopenharmony_ci if (transport.empty()) { 508e0e9324cSopenharmony_ci return 0; 509e0e9324cSopenharmony_ci } 510e0e9324cSopenharmony_ci 511e0e9324cSopenharmony_ci auto tsVec = RtspCommon::Split(transport, ";"); 512e0e9324cSopenharmony_ci for (auto &item : tsVec) { 513e0e9324cSopenharmony_ci if (item.find("client_port=") != std::string::npos) { 514e0e9324cSopenharmony_ci auto val = item.substr(item.find('=') + 1); 515e0e9324cSopenharmony_ci return atoi(val.c_str()); 516e0e9324cSopenharmony_ci } 517e0e9324cSopenharmony_ci } 518e0e9324cSopenharmony_ci 519e0e9324cSopenharmony_ci return 0; 520e0e9324cSopenharmony_ci} 521e0e9324cSopenharmony_ci 522e0e9324cSopenharmony_ciint32_t WfdRtspM6Response::GetServerPort() 523e0e9324cSopenharmony_ci{ 524e0e9324cSopenharmony_ci auto transport = GetToken(RTSP_TOKEN_TRANSPORT); 525e0e9324cSopenharmony_ci if (transport.empty()) { 526e0e9324cSopenharmony_ci return 0; 527e0e9324cSopenharmony_ci } 528e0e9324cSopenharmony_ci 529e0e9324cSopenharmony_ci auto tsVec = RtspCommon::Split(transport, ";"); 530e0e9324cSopenharmony_ci for (auto &item : tsVec) { 531e0e9324cSopenharmony_ci if (item.find("server_port=") != std::string::npos) { 532e0e9324cSopenharmony_ci auto val = item.substr(item.find('=') + 1); 533e0e9324cSopenharmony_ci return atoi(val.c_str()); 534e0e9324cSopenharmony_ci } 535e0e9324cSopenharmony_ci } 536e0e9324cSopenharmony_ci 537e0e9324cSopenharmony_ci return 0; 538e0e9324cSopenharmony_ci} 539e0e9324cSopenharmony_ci 540e0e9324cSopenharmony_civoid WfdRtspM6Response::SetClientPort(int port) 541e0e9324cSopenharmony_ci{ 542e0e9324cSopenharmony_ci clientPort_ = port; 543e0e9324cSopenharmony_ci} 544e0e9324cSopenharmony_ci 545e0e9324cSopenharmony_civoid WfdRtspM6Response::SetServerPort(int port) 546e0e9324cSopenharmony_ci{ 547e0e9324cSopenharmony_ci serverPort_ = port; 548e0e9324cSopenharmony_ci} 549e0e9324cSopenharmony_ci 550e0e9324cSopenharmony_cistd::string WfdRtspM6Response::StringifyEx() 551e0e9324cSopenharmony_ci{ 552e0e9324cSopenharmony_ci std::stringstream ss; 553e0e9324cSopenharmony_ci auto message = Stringify(); 554e0e9324cSopenharmony_ci std::string temp = RTSP_CRLF; 555e0e9324cSopenharmony_ci auto nPos = message.find_last_of(RTSP_CRLF); 556e0e9324cSopenharmony_ci if (nPos != std::string::npos) { 557e0e9324cSopenharmony_ci message = message.substr(0, message.size() - temp.size()); 558e0e9324cSopenharmony_ci } 559e0e9324cSopenharmony_ci ss << message << "Transport: RTP/AVP/UDP;unicast;client_port=" << clientPort_ << ";server_port=" << serverPort_ 560e0e9324cSopenharmony_ci << RTSP_CRLF; 561e0e9324cSopenharmony_ci ss << RTSP_CRLF; 562e0e9324cSopenharmony_ci return ss.str(); 563e0e9324cSopenharmony_ci} 564e0e9324cSopenharmony_ci 565e0e9324cSopenharmony_cistd::string WfdRtspM7Response::StringifyEx() 566e0e9324cSopenharmony_ci{ 567e0e9324cSopenharmony_ci std::stringstream ss; 568e0e9324cSopenharmony_ci auto message = Stringify(); 569e0e9324cSopenharmony_ci std::string temp = RTSP_CRLF; 570e0e9324cSopenharmony_ci auto nPos = message.find_last_of(RTSP_CRLF); 571e0e9324cSopenharmony_ci if (nPos != std::string::npos) { 572e0e9324cSopenharmony_ci message = message.substr(0, message.size() - temp.size()); 573e0e9324cSopenharmony_ci } 574e0e9324cSopenharmony_ci ss << message << "Range: npt=now-" << RTSP_CRLF; 575e0e9324cSopenharmony_ci ss << RTSP_CRLF; 576e0e9324cSopenharmony_ci return ss.str(); 577e0e9324cSopenharmony_ci} 578e0e9324cSopenharmony_ci 579e0e9324cSopenharmony_ci} // namespace Sharing 580e0e9324cSopenharmony_ci} // namespace OHOS 581