From 19815d624acf4368131ad7ab879cf4879de18a4c Mon Sep 17 00:00:00 2001 From: wangshuo <584363327@qq.com> Date: Thu, 31 Aug 2023 16:58:29 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E6=B8=B2=E6=9F=93=E6=97=B6=E5=BB=B6?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/cpp/cas_decoder/CasDecoder.cpp | 45 ++++++++++++++++--- .../src/main/cpp/cas_decoder/CasDecoder.h | 7 ++- 2 files changed, 46 insertions(+), 6 deletions(-) diff --git a/cloudphone/src/main/cpp/cas_decoder/CasDecoder.cpp b/cloudphone/src/main/cpp/cas_decoder/CasDecoder.cpp index 7744c1d..ade3fed 100644 --- a/cloudphone/src/main/cpp/cas_decoder/CasDecoder.cpp +++ b/cloudphone/src/main/cpp/cas_decoder/CasDecoder.cpp @@ -32,7 +32,7 @@ namespace { 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"; - const char *HW_H265_DECODER_NAME = " OMX.hisi.video.decoder.hevc"; + const char *HW_H265_DECODER_NAME = "OMX.hisi.video.decoder.hevc"; // the end-of-picture bits appending to the origin h264 frame const uint8_t H264_NAL_EOPIC[] = { 0x00, 0x00, 0x01, 0x1D, @@ -141,6 +141,7 @@ uint32_t CasDecoder::Start() ERR("Failed to start MediaCodec, errno: %d.", rc); return DECODER_START_ERR; } + m_isStreamBeginFrame = false; INFO("Start MediaCodec success."); return DECODER_SUCCESS; } @@ -156,7 +157,16 @@ uint32_t CasDecoder::Start() */ uint32_t CasDecoder::Input(const uint8_t *buf, const size_t len) { - size_t dataLen = ISNeedAppendMockFrameBytes() ? sizeof(H264_NAL_EOPIC) + len : len; + if (!m_isStreamBeginFrame) { + if(IsStreamBeginFrame(buf)) { + m_isStreamBeginFrame = false; + m_inputFrameCount = 0; + m_outputFrameCount = 0; + } else { + return DECODER_SUCCESS; + } + } + size_t dataLen = IsNeedAppendMockFrameBytes() ? sizeof(H264_NAL_EOPIC) + len : len; uint8_t *data = AssembleMemory(buf, len); if (data == nullptr) { ERR("Failed to assemble memory."); @@ -191,6 +201,9 @@ uint32_t CasDecoder::Input(const uint8_t *buf, const size_t len) Destroy(); FreeBuffer(data); return DECODER_INPUT_ERR; + } else { + m_inputFrameCount++; + DBG("DecodeLog: input frame count = %d, size = %d", m_inputFrameCount, len); } if (ENABLE_DECODE_LOG) { char logBuf[1024] = {0}; @@ -224,11 +237,20 @@ uint32_t CasDecoder::OutputAndDisplay() sprintf_s(logBuf, sizeof(logBuf) - 1, "Frame(%" PRIu64 ") @buffer(%zd) output success, decode latency %" PRIu64 " ms", frameUs, bufId, latency); + DBG("DecodeLog: frame count %d decode latency is %d", m_outputFrameCount, latency); } // If you are done with a buffer, use this call to return the buffer to the codec. // If you have not specified an output surface when configuring this video codec, // this call will simply return the buffer to the codec. - auto rc = AMediaCodec_releaseOutputBuffer(m_mediaCodec, bufId, true); + m_outputFrameCount++; + DBG("DecodeLog: dequeue output buffer success: bufId = %d, m_outputFrameCount = %d", bufId, m_outputFrameCount); + + if (m_inputFrameCount - m_outputFrameCount > 1) { + DBG("DecodeLog: frame count %d output buffer latency exceed %d frames, release one frame. ", m_outputFrameCount, m_inputFrameCount - m_outputFrameCount); + AMediaCodec_releaseOutputBuffer(m_mediaCodec, bufId, false); + } else { + AMediaCodec_releaseOutputBuffer(m_mediaCodec, bufId, true); + } return DECODER_SUCCESS; } switch (bufId) { @@ -327,7 +349,7 @@ AMediaFormat *CasDecoder:: CreateMediaCodecFmt(int rotationDegrees) const */ uint8_t *CasDecoder::AssembleMemory(const uint8_t *buf, const size_t len) const { - bool needAppendBytes = ISNeedAppendMockFrameBytes(); + bool needAppendBytes = IsNeedAppendMockFrameBytes(); uint32_t size = needAppendBytes ? sizeof(H264_NAL_EOPIC) + len : len; uint8_t *data = reinterpret_cast(AllocBuffer(size)); if (data == nullptr) { @@ -434,7 +456,7 @@ bool CasDecoder::ISQcom() const return strcmp(hardware, "qcom") == 0; } -bool CasDecoder::ISNeedAppendMockFrameBytes() const +bool CasDecoder::IsNeedAppendMockFrameBytes() const { return m_isHuawei && m_frameType == FrameType::H264; } @@ -445,4 +467,17 @@ uint64_t CasDecoder::GetCurrentTimeMs() const timespec now; clock_gettime(CLOCK_REALTIME, &now); return static_cast(now.tv_sec * oneSecond + now.tv_nsec / (oneSecond * oneSecond)); +} + +bool CasDecoder::IsStreamBeginFrame(const uint8_t *buf) const +{ + if (buf[0] != 0x00 || buf[1] != 0x00 || buf[2] != 0x00 || buf[3] != 0x01) { + return false; + } + if (m_frameType == FrameType::H265) { + return buf[4] == 0x40 || buf[4] == 0x46; + } else if (m_frameType == FrameType::H264) { + return buf[4] == 0x67; + } + return false; } \ No newline at end of file diff --git a/cloudphone/src/main/cpp/cas_decoder/CasDecoder.h b/cloudphone/src/main/cpp/cas_decoder/CasDecoder.h index d0a1629..cb28fb3 100644 --- a/cloudphone/src/main/cpp/cas_decoder/CasDecoder.h +++ b/cloudphone/src/main/cpp/cas_decoder/CasDecoder.h @@ -134,7 +134,9 @@ private: bool ISQcom() const; - bool ISNeedAppendMockFrameBytes() const; + bool IsNeedAppendMockFrameBytes() const; + + bool IsStreamBeginFrame(const uint8_t *buf) const; uint64_t GetCurrentTimeMs() const; @@ -145,6 +147,9 @@ private: const char *m_mimeType; bool m_isHuawei = false; bool m_isQcom = false; + uint32_t m_outputFrameCount = 0; + uint32_t m_inputFrameCount = 0; + bool m_isStreamBeginFrame = false; }; #endif // CLOUDAPPSDK_CASDECODER_H \ No newline at end of file -- Gitee From e4086f897f6c87f96452539d3e965ab9ee5f23a5 Mon Sep 17 00:00:00 2001 From: wangshuo <584363327@qq.com> Date: Thu, 31 Aug 2023 17:04:12 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E5=BC=BA=E5=88=B6=E4=B8=8B=E7=BA=BF?= =?UTF-8?q?=E6=97=B6=E6=8F=90=E5=89=8D=E9=80=80=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/huawei/cloudapp/ui/CasCloudPhoneActivity.java | 5 +++++ 1 file changed, 5 insertions(+) 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 e33eb16..9cf0a6f 100644 --- a/app/src/main/java/com/huawei/cloudapp/ui/CasCloudPhoneActivity.java +++ b/app/src/main/java/com/huawei/cloudapp/ui/CasCloudPhoneActivity.java @@ -484,6 +484,11 @@ public class CasCloudPhoneActivity extends FragmentActivity implements View.OnCl showDialog(getResources().getString(R.string.cas_phone_start_auth_fail_tip_message)); break; case CasState.CAS_VERIFY_SESSION_ID_INVALID: + try { + mCloudPhone.exitCloudPhone(); + } catch (Exception e) { + CASLog.e(TAG, "Stop cloud phone failed. ", e.getMessage()); + } showDialog(getResources().getString(R.string.cas_phone_session_invalid_tip_message)); break; case CasState.CAS_TRAIL_PLAY_TIMEOUT: -- Gitee From 0267eae87371891210cc6a4c9da50afb91f92697 Mon Sep 17 00:00:00 2001 From: wangshuo <584363327@qq.com> Date: Thu, 31 Aug 2023 17:12:12 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E6=B8=B2=E6=9F=93=E6=97=B6=E5=BB=B6?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloudphone/src/main/cpp/cas_decoder/CasDecoder.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloudphone/src/main/cpp/cas_decoder/CasDecoder.cpp b/cloudphone/src/main/cpp/cas_decoder/CasDecoder.cpp index ade3fed..40f050d 100644 --- a/cloudphone/src/main/cpp/cas_decoder/CasDecoder.cpp +++ b/cloudphone/src/main/cpp/cas_decoder/CasDecoder.cpp @@ -159,7 +159,7 @@ uint32_t CasDecoder::Input(const uint8_t *buf, const size_t len) { if (!m_isStreamBeginFrame) { if(IsStreamBeginFrame(buf)) { - m_isStreamBeginFrame = false; + m_isStreamBeginFrame = true; m_inputFrameCount = 0; m_outputFrameCount = 0; } else { -- Gitee From db0a1afa7b007ed1a50efb57c0bf090c0a65c9ee Mon Sep 17 00:00:00 2001 From: wangshuo <584363327@qq.com> Date: Thu, 31 Aug 2023 18:05:35 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E6=B8=B2=E6=9F=93=E6=97=B6=E5=BB=B6?= =?UTF-8?q?=E4=BC=98=E5=8C=96-=E9=81=BF=E5=85=8D=E8=BF=9E=E7=BB=AD?= =?UTF-8?q?=E4=B8=A2=E5=B8=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloudphone/src/main/cpp/cas_decoder/CasDecoder.cpp | 4 +++- cloudphone/src/main/cpp/cas_decoder/CasDecoder.h | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/cloudphone/src/main/cpp/cas_decoder/CasDecoder.cpp b/cloudphone/src/main/cpp/cas_decoder/CasDecoder.cpp index 40f050d..2259a62 100644 --- a/cloudphone/src/main/cpp/cas_decoder/CasDecoder.cpp +++ b/cloudphone/src/main/cpp/cas_decoder/CasDecoder.cpp @@ -245,11 +245,13 @@ uint32_t CasDecoder::OutputAndDisplay() m_outputFrameCount++; DBG("DecodeLog: dequeue output buffer success: bufId = %d, m_outputFrameCount = %d", bufId, m_outputFrameCount); - if (m_inputFrameCount - m_outputFrameCount > 1) { + if (m_inputFrameCount - m_outputFrameCount > 1 && !m_isDropFrame) { DBG("DecodeLog: frame count %d output buffer latency exceed %d frames, release one frame. ", m_outputFrameCount, m_inputFrameCount - m_outputFrameCount); AMediaCodec_releaseOutputBuffer(m_mediaCodec, bufId, false); + m_isDropFrame = true; } else { AMediaCodec_releaseOutputBuffer(m_mediaCodec, bufId, true); + m_isDropFrame = false; } return DECODER_SUCCESS; } diff --git a/cloudphone/src/main/cpp/cas_decoder/CasDecoder.h b/cloudphone/src/main/cpp/cas_decoder/CasDecoder.h index cb28fb3..d3868b1 100644 --- a/cloudphone/src/main/cpp/cas_decoder/CasDecoder.h +++ b/cloudphone/src/main/cpp/cas_decoder/CasDecoder.h @@ -150,6 +150,7 @@ private: uint32_t m_outputFrameCount = 0; uint32_t m_inputFrameCount = 0; bool m_isStreamBeginFrame = false; + bool m_isDropFrame = false; }; #endif // CLOUDAPPSDK_CASDECODER_H \ No newline at end of file -- Gitee