diff --git a/app/src/main/java/com/huawei/cloudapp/ui/CasCloudPhoneActivity.java b/app/src/main/java/com/huawei/cloudapp/ui/CasCloudPhoneActivity.java index cd098ab895dbb6f962322f5af50230e5a6ca6e68..424cbe99751afb009be8edda34f915f87a8d4c62 100644 --- a/app/src/main/java/com/huawei/cloudapp/ui/CasCloudPhoneActivity.java +++ b/app/src/main/java/com/huawei/cloudapp/ui/CasCloudPhoneActivity.java @@ -94,7 +94,7 @@ import static com.huawei.cloudphone.virtualdevice.common.VirtualDeviceManager.DE import static com.huawei.cloudphone.virtualdevice.microphone.VirtualMicrophoneManager.GRANT_MICROPHONE_PERMISSION_SUCCESS_ACTION; public class CasCloudPhoneActivity extends FragmentActivity implements View.OnClickListener { - private static final String TAG = "CasMainActivity"; + private static final String TAG = "CasCloudPhoneActivity"; // Intent Trans Key public static final String ORIENTATION = "orientation"; diff --git a/cloudphone/src/main/cpp/CasCommon.h b/cloudphone/src/main/cpp/CasCommon.h index 01d70e112ddef7348292fc8751e7cad998d3e78d..3b75466cd3c56cd0f5a570e273e2e6e47128528a 100644 --- a/cloudphone/src/main/cpp/CasCommon.h +++ b/cloudphone/src/main/cpp/CasCommon.h @@ -35,6 +35,7 @@ const std::string KEY_MEDIA_CONFIG = "media_config"; const std::string KEY_USER_ID = "user_id"; const std::string KEY_FRAME_RATE = "frame_rate"; +const std::string KEY_FRAME_TYPE = "frame_type"; const std::string KEY_BITRATE = "bitrate"; const std::string KEY_VIRTUAL_WIDTH = "virtual_width"; const std::string KEY_VIRTUAL_HEIGHT = "virtual_height"; diff --git a/cloudphone/src/main/cpp/CasController.cpp b/cloudphone/src/main/cpp/CasController.cpp index 02bbf973cbbf8919fd93eeb08870c9ca59252403..2b5a948d9ae579c52a4548931db18aca595a9fbe 100644 --- a/cloudphone/src/main/cpp/CasController.cpp +++ b/cloudphone/src/main/cpp/CasController.cpp @@ -153,6 +153,14 @@ bool CasController::Start(ANativeWindow *nativeWindow, bool isHome) m_clientType = CLIENT_TYPE; m_maxDisconnectDuration = CalcMaxDisconnectDuration(m_conf.backgroundTimeout); + std::string mediaConfigStr = ""; + if (IsValidMediaConfig(m_mediaConfig)) { + mediaConfigStr = CasAppCtrlCmdUtils::MakeCommand(m_mediaConfig, SUB_COMMAND_SEPARATOR); + } + if (m_mediaConfig.find(KEY_FRAME_TYPE) != m_mediaConfig.end()) { + m_frameType = m_mediaConfig[KEY_FRAME_TYPE] == "h264" ? FrameType::H264 : FrameType::H265; + } + res = InitDataStream(); if (!res) { CloseDataStream(); @@ -173,10 +181,6 @@ bool CasController::Start(ANativeWindow *nativeWindow, bool isHome) StartWorkers(!m_retainVideoDecode); std::string startCmd = CMD_START_APP; - std::string mediaConfigStr = ""; - if (IsValidMediaConfig(m_mediaConfig)) { - mediaConfigStr = CasAppCtrlCmdUtils::MakeCommand(m_mediaConfig, SUB_COMMAND_SEPARATOR); - } map parameters = { { KEY_COMMAND, startCmd }, { KEY_TICKET, m_ticket }, { KEY_AUTH_TS, m_authTs }, @@ -403,7 +407,7 @@ bool CasController::CreateWorkers(ANativeWindow *nativeWindow, bool needVideoDec m_streamParser->SetServiceHandle(CasMsgType::VirtualDevice, m_virtualDeviceStream); if (needVideoDecode) { - m_videoDecodeThread = new (std::nothrow) CasVideoHDecodeThread(nativeWindow); + m_videoDecodeThread = new (std::nothrow) CasVideoHDecodeThread(nativeWindow, m_frameType); if (m_videoDecodeThread == nullptr) { ERR("Failed to new video decode thread."); return false; @@ -844,7 +848,7 @@ bool CasController::ProcessEnterForeground(ANativeWindow *nativeWindow) bool CasController::CreateDecWorker(ANativeWindow *nativeWindow, bool needVideoDecode) { if (needVideoDecode) { - m_videoDecodeThread = new (std::nothrow) CasVideoHDecodeThread(nativeWindow); + m_videoDecodeThread = new (std::nothrow) CasVideoHDecodeThread(nativeWindow, m_frameType); if (m_videoDecodeThread == nullptr) { return false; } diff --git a/cloudphone/src/main/cpp/CasController.h b/cloudphone/src/main/cpp/CasController.h index 8711702b49e9becb18cf4c0d08e30326a5447422..02b111d3c22a35edff790c46435d07e8c6e664be 100644 --- a/cloudphone/src/main/cpp/CasController.h +++ b/cloudphone/src/main/cpp/CasController.h @@ -152,6 +152,7 @@ private: std::string m_aesIv; std::string m_clientType; std::string m_maxDisconnectDuration; + FrameType m_frameType; unsigned int m_ip = 0; unsigned short m_port = 0; const bool m_retainVideoDecode = true; diff --git a/cloudphone/src/main/cpp/cas_decoder/CasDecodeController.cpp b/cloudphone/src/main/cpp/cas_decoder/CasDecodeController.cpp index cced19e1123d1bca2bf0610180e88ee567e25d57..16290b732699fd076a0ea4bbbd08b520004e0d17 100644 --- a/cloudphone/src/main/cpp/cas_decoder/CasDecodeController.cpp +++ b/cloudphone/src/main/cpp/cas_decoder/CasDecodeController.cpp @@ -121,7 +121,7 @@ void OutputTaskEntry(CasDecodeController *controller) * @return errno: SUCCESS * VIDEO_ENGINE_CLIENT_INIT_FAIL */ -uint32_t CasDecodeController::Init(ANativeWindow *nativeWindow) +uint32_t CasDecodeController::Init(ANativeWindow *nativeWindow, FrameType frameType) { if (!IsStatus(EngineStat::ENGINE_INVALID)) { ERR("Destroy needed first."); @@ -132,7 +132,7 @@ uint32_t CasDecodeController::Init(ANativeWindow *nativeWindow) ERR("Failed to instantiate CasDecoder."); return VIDEO_ENGINE_CLIENT_INIT_FAIL; } - uint32_t ret = m_decoder->Init(nativeWindow); + uint32_t ret = m_decoder->Init(nativeWindow, frameType); if (ret != DECODER_SUCCESS) { Destroy(); if (ret == DECODER_SDK_UNSUPPORTED) { diff --git a/cloudphone/src/main/cpp/cas_decoder/CasDecodeController.h b/cloudphone/src/main/cpp/cas_decoder/CasDecodeController.h index 96829493af2764b998ad7ee6aabeea91dacd9fb7..2201c506767a4b54939330712ff076fcbc7d36d0 100644 --- a/cloudphone/src/main/cpp/cas_decoder/CasDecodeController.h +++ b/cloudphone/src/main/cpp/cas_decoder/CasDecodeController.h @@ -45,7 +45,7 @@ public: * @return errno: SUCCESS * VIDEO_ENGINE_CLIENT_INIT_FAIL */ - uint32_t Init(ANativeWindow *nativeWindow); + uint32_t Init(ANativeWindow *nativeWindow, FrameType frameType); /* * @fn Start diff --git a/cloudphone/src/main/cpp/cas_decoder/CasDecoder.cpp b/cloudphone/src/main/cpp/cas_decoder/CasDecoder.cpp index a32150ce98ae976f116bb318fbedab870c00d9a8..fce69c896253093f9af50ee2e1a3eec4e6072562 100644 --- a/cloudphone/src/main/cpp/cas_decoder/CasDecoder.cpp +++ b/cloudphone/src/main/cpp/cas_decoder/CasDecoder.cpp @@ -29,7 +29,8 @@ namespace { KEY_WIDTH = 720, KEY_HEIGHT = 1280 }; - const char *MIME_TYPE = "video/avc"; + const char *MIME_TYPE_H264 = "video/avc"; + const char *MIME_TYPE_H265 = "video/hevc"; const char *HW_H264_DECODER_NAME = "OMX.hisi.video.decoder.avc"; // the end-of-picture bits appending to the origin h264 frame const uint8_t H264_NAL_EOPIC[] = { @@ -77,7 +78,7 @@ CasDecoder::~CasDecoder() * @return errno: DECODER_SUCCESS * DECODER_INIT_ERR */ -uint32_t CasDecoder::Init(ANativeWindow *nativeWindow) +uint32_t CasDecoder::Init(ANativeWindow *nativeWindow, FrameType frameType) { m_casVideoUtil = CasVideoUtil::GetInstance(); if (m_casVideoUtil == nullptr || !m_casVideoUtil->Init()) { @@ -91,15 +92,15 @@ uint32_t CasDecoder::Init(ANativeWindow *nativeWindow) INFO("DECODER_SDK_UNSUPPORTED m_sdkNo = %d", m_sdkNo); return DECODER_SDK_UNSUPPORTED; } - + m_mimeType = frameType == FrameType::H264 ? MIME_TYPE_H264 : MIME_TYPE_H265; if (m_isHuawei && m_sdkNo >= SDK_VERSION_BORDER) { m_mediaCodec = AMediaCodec_createCodecByName(HW_H264_DECODER_NAME); if (m_mediaCodec == nullptr) { - m_mediaCodec = AMediaCodec_createDecoderByType(MIME_TYPE); + m_mediaCodec = AMediaCodec_createDecoderByType(m_mimeType); m_isHuawei = false; } } else { - m_mediaCodec = AMediaCodec_createDecoderByType(MIME_TYPE); + m_mediaCodec = AMediaCodec_createDecoderByType(m_mimeType); } if (m_mediaCodec == nullptr) { @@ -282,7 +283,7 @@ AMediaFormat *CasDecoder::CreateMediaCodecFmt() const { AMediaFormat *fmt = AMediaFormat_new(); if (fmt != nullptr) { - AMediaFormat_setString(fmt, AMEDIAFORMAT_KEY_MIME, MIME_TYPE); + AMediaFormat_setString(fmt, AMEDIAFORMAT_KEY_MIME, m_mimeType); AMediaFormat_setInt32(fmt, AMEDIAFORMAT_KEY_WIDTH, MediaCodecResolution::KEY_WIDTH); AMediaFormat_setInt32(fmt, AMEDIAFORMAT_KEY_HEIGHT, MediaCodecResolution::KEY_HEIGHT); // Operate at maximum rate to lower latency as much as possible on @@ -423,7 +424,7 @@ bool CasDecoder::ISQcom() const bool CasDecoder::ISNeedAppendMockFrameBytes() const { - return m_isHuawei; + return m_isHuawei && m_frameType == FrameType::H264; } uint64_t CasDecoder::GetCurrentTimeMs() const diff --git a/cloudphone/src/main/cpp/cas_decoder/CasDecoder.h b/cloudphone/src/main/cpp/cas_decoder/CasDecoder.h index 4b149f7e8e666a89579bc3e0428a5143f936cfb5..60df65e6d7d601ba77406e117caa1c71e48bd21c 100644 --- a/cloudphone/src/main/cpp/cas_decoder/CasDecoder.h +++ b/cloudphone/src/main/cpp/cas_decoder/CasDecoder.h @@ -19,6 +19,7 @@ #include #include #include "CasVideoUtil.h" +#include "CasVideoEngineCommon.h" const uint32_t DECODER_SUCCESS = 0; const uint32_t DECODER_INIT_ERR = 0x01; @@ -49,7 +50,7 @@ public: * @return errno: DECODER_SUCCESS * DECODER_INIT_ERR */ - uint32_t Init(ANativeWindow *nativeWindow); + uint32_t Init(ANativeWindow *nativeWindow, FrameType frameType); /* * @fn Start @@ -139,6 +140,8 @@ private: AMediaCodec *m_mediaCodec = nullptr; CasVideoUtil *m_casVideoUtil = nullptr; int m_sdkNo = 0; + FrameType m_frameType = FrameType::H264; + const char *m_mimeType; bool m_isHuawei = false; bool m_isQcom = false; }; diff --git a/cloudphone/src/main/cpp/cas_decoder/CasVideoEngine.cpp b/cloudphone/src/main/cpp/cas_decoder/CasVideoEngine.cpp index 586b4b3076423b70773c42fcf1cdb85401ac7893..e7eedc9cd10ad447e8f245110c8f0e5c33143b46 100644 --- a/cloudphone/src/main/cpp/cas_decoder/CasVideoEngine.cpp +++ b/cloudphone/src/main/cpp/cas_decoder/CasVideoEngine.cpp @@ -42,7 +42,7 @@ CasVideoEngine::~CasVideoEngine() = default; * VIDEO_ENGINE_CLIENT_PARAM_INVALID * VIDEO_ENGINE_CLIENT_PARAM_UNSUPPORTED */ -uint32_t CasVideoEngine::InitDecoder(ANativeWindow *nativeWindow, DecoderType type) +uint32_t CasVideoEngine::InitDecoder(ANativeWindow *nativeWindow, DecoderType type, FrameType frameType) { std::lock_guard lockGuard(m_lock); if (nativeWindow == nullptr) { @@ -58,7 +58,7 @@ uint32_t CasVideoEngine::InitDecoder(ANativeWindow *nativeWindow, DecoderType ty ERR("Failed to instantiate."); return VIDEO_ENGINE_CLIENT_INIT_FAIL; } - return decodeController->Init(nativeWindow); + return decodeController->Init(nativeWindow, frameType); } /* diff --git a/cloudphone/src/main/cpp/cas_decoder/CasVideoEngine.h b/cloudphone/src/main/cpp/cas_decoder/CasVideoEngine.h index 497acbf727fe9fda1e6475a3612985ffc9cc4e5c..8a374b11b67df062a2ca54dafb468c1f8df42187 100644 --- a/cloudphone/src/main/cpp/cas_decoder/CasVideoEngine.h +++ b/cloudphone/src/main/cpp/cas_decoder/CasVideoEngine.h @@ -44,7 +44,7 @@ public: * VIDEO_ENGINE_CLIENT_PARAM_INVALID * VIDEO_ENGINE_CLIENT_PARAM_UNSUPPORTED */ - uint32_t InitDecoder(ANativeWindow *nativeWindow, DecoderType type); + uint32_t InitDecoder(ANativeWindow *nativeWindow, DecoderType type, FrameType frameType); /* * @fn StartDecoder diff --git a/cloudphone/src/main/cpp/cas_decoder/CasVideoEngineCommon.h b/cloudphone/src/main/cpp/cas_decoder/CasVideoEngineCommon.h index d80f8d9794be6f42610586538ee607f0533052dc..0d76c128d8cc364e4ec9b81baba4c0802079700d 100644 --- a/cloudphone/src/main/cpp/cas_decoder/CasVideoEngineCommon.h +++ b/cloudphone/src/main/cpp/cas_decoder/CasVideoEngineCommon.h @@ -22,6 +22,12 @@ enum class DecoderType { DECODER_TYPE_HW = 0 }; +// CasDecoder FrameType +enum class FrameType { + H264 = 0, + H265 +}; + // Video Engine Status enum class EngineStat { ENGINE_INIT = 0x01, diff --git a/cloudphone/src/main/cpp/cas_service/CasVideoHDecodeThread.cpp b/cloudphone/src/main/cpp/cas_service/CasVideoHDecodeThread.cpp index 7357ccd48f51bfbe027763458fadb0dfd5bf5ef9..6417558dd95129b4c9470f04954865d9263844f3 100644 --- a/cloudphone/src/main/cpp/cas_service/CasVideoHDecodeThread.cpp +++ b/cloudphone/src/main/cpp/cas_service/CasVideoHDecodeThread.cpp @@ -40,7 +40,7 @@ public: } }; -CasVideoHDecodeThread::CasVideoHDecodeThread(ANativeWindow *nativeWindow) +CasVideoHDecodeThread::CasVideoHDecodeThread(ANativeWindow *nativeWindow, FrameType frameType) { this->m_nativeWindow = nativeWindow; this->m_videoEngine = nullptr; @@ -49,6 +49,7 @@ CasVideoHDecodeThread::CasVideoHDecodeThread(ANativeWindow *nativeWindow) this->m_videoPktStream = nullptr; this->m_decodeTask = nullptr; this->m_threadStatus = CAS_THREAD_INIT; + this->m_frameType = frameType; } CasVideoHDecodeThread::~CasVideoHDecodeThread() @@ -197,7 +198,7 @@ int CasVideoHDecodeThread::Start() } this->m_videoEngine->SetVideoDecodeStatListener(m_videoDecodeStat); - uint32_t initRet = this->m_videoEngine->InitDecoder(this->m_nativeWindow, DecoderType::DECODER_TYPE_HW); + uint32_t initRet = this->m_videoEngine->InitDecoder(this->m_nativeWindow, DecoderType::DECODER_TYPE_HW, m_frameType); if (initRet != 0) { ERR("Init error %u", initRet); EngineStat status; @@ -212,7 +213,7 @@ int CasVideoHDecodeThread::Start() INFO("Get decoder status error."); return initRet; } - initRet = this->m_videoEngine->InitDecoder(this->m_nativeWindow, DecoderType::DECODER_TYPE_HW); + initRet = this->m_videoEngine->InitDecoder(this->m_nativeWindow, DecoderType::DECODER_TYPE_HW, m_frameType); if (initRet != 0) { ERR("Init again return error %u.", initRet); return initRet; diff --git a/cloudphone/src/main/cpp/cas_service/CasVideoHDecodeThread.h b/cloudphone/src/main/cpp/cas_service/CasVideoHDecodeThread.h index 6e08e4e235bd809505ba42d506e677b59256a5fb..23b59413ce0b59ef1616b9eb38c920aa071b0b17 100644 --- a/cloudphone/src/main/cpp/cas_service/CasVideoHDecodeThread.h +++ b/cloudphone/src/main/cpp/cas_service/CasVideoHDecodeThread.h @@ -25,7 +25,7 @@ class CasVideoDecodeStatImpl; class CasVideoHDecodeThread { public: - explicit CasVideoHDecodeThread(ANativeWindow *nativeWindow); + explicit CasVideoHDecodeThread(ANativeWindow *nativeWindow, FrameType frameType); ~CasVideoHDecodeThread(); @@ -56,6 +56,7 @@ private: std::atomic_int m_threadStatus; std::thread *m_decodeTask; ANativeWindow *m_nativeWindow; + FrameType m_frameType; }; #endif // CLOUDAPPSDK_CASVIDEODECODETHREAD_H