diff options
author | Bodam Nam <bodamnam@google.com> | 2023-04-21 06:06:54 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2023-04-21 06:06:54 +0000 |
commit | 494e31177e46ec3b989f569d9fec010fa55df867 (patch) | |
tree | 77daebc4c4c41dae651a3425504a52dd1ccc21b1 | |
parent | cc53a68a4149caa42e41dd3b5964bedb8962eac6 (diff) | |
parent | 1879ee137ede0d62b88cd16da3d46138ca540dfa (diff) | |
download | ImsMedia-494e31177e46ec3b989f569d9fec010fa55df867.tar.gz |
Merge "Fix the HEVC codec decoding failure in video call" into udc-dev am: 1879ee137eaml_wif_341711020aml_wif_341610000aml_wif_341510000aml_wif_341410080aml_wif_341310010aml_wif_341110010aml_wif_341011010aml_wif_340913010aml_uwb_341710010aml_uwb_341513070aml_uwb_341511050aml_uwb_341310300aml_uwb_341310030aml_uwb_341111010aml_uwb_341011000aml_tet_341712060aml_tet_341610020aml_tet_341511010aml_tet_341411060aml_tet_341310230aml_tet_341112070aml_tet_341010040aml_tet_340913030aml_swc_341711000aml_swc_341619000aml_swc_341513600aml_swc_341312300aml_swc_341312020aml_swc_341111000aml_swc_341011020aml_swc_340922010aml_sta_341710000aml_sta_341615000aml_sta_341511040aml_sta_341410000aml_sta_341311010aml_sta_341114000aml_sta_341111000aml_sta_341010020aml_sta_340912000aml_sta_340911000aml_sdk_341710000aml_sdk_341510000aml_sdk_341410000aml_sdk_341110080aml_sdk_341110000aml_sdk_341010000aml_sdk_340912010aml_sch_341510000aml_res_341510000aml_res_341410010aml_res_341311030aml_res_341110000aml_res_340912000aml_per_341711000aml_per_341614000aml_per_341510010aml_per_341410020aml_per_341311000aml_per_341110020aml_per_341110010aml_per_341011100aml_per_341011020aml_per_340916010aml_odp_341717000aml_odp_341610000aml_neu_341510000aml_neu_341010080aml_neu_341010000aml_net_341710020aml_net_341610030aml_net_341510050aml_net_341510000aml_net_341411030aml_net_341311010aml_net_341310020aml_net_341111030aml_net_341014000aml_net_340913000aml_mpr_341713020aml_mpr_341614010aml_mpr_341511070aml_mpr_341411070aml_mpr_341313030aml_mpr_341111030aml_mpr_341111020aml_mpr_341015090aml_mpr_341015030aml_mpr_340919000aml_med_341711000aml_med_341619000aml_med_341513600aml_med_341312300aml_med_341312020aml_med_341111000aml_med_341011000aml_med_340922010aml_ips_341611000aml_ips_341510000aml_ips_340914280aml_ips_340914200aml_ips_340914000aml_ext_341716000aml_ext_341620040aml_ext_341518010aml_ext_341414010aml_ext_341317010aml_ext_341131030aml_ext_341027030aml_doc_341713000aml_doc_341610010aml_doc_341510050aml_doc_341312010aml_doc_341112000aml_doc_341012000aml_doc_340916000aml_con_341614000aml_con_341511080aml_con_341410300aml_con_341310090aml_con_341110000aml_cbr_341710000aml_cbr_341610000aml_cbr_341510010aml_cbr_341410010aml_cbr_341311010aml_cbr_341110000aml_cbr_341011000aml_cbr_340914000aml_ase_341510000aml_ase_341410000aml_ase_341310010aml_ase_341113000aml_ase_340913000aml_art_341711000aml_art_341615020aml_art_341514450aml_art_341514410aml_art_341411300aml_art_341311100aml_art_341110110aml_art_341110060aml_art_341010050aml_art_340915060aml_ads_341720000aml_ads_341615050aml_ads_341517040aml_ads_341413000aml_ads_341316030aml_ads_341131050aml_ads_341027030aml_ads_340915050aml_adb_341520010aml_adb_341517070aml_adb_340912530aml_adb_340912350aml_adb_340912200aml_adb_340912000android14-mainline-wifi-releaseandroid14-mainline-uwb-releaseandroid14-mainline-tethering-releaseandroid14-mainline-sdkext-releaseandroid14-mainline-resolv-releaseandroid14-mainline-permission-releaseandroid14-mainline-os-statsd-releaseandroid14-mainline-networking-releaseandroid14-mainline-mediaprovider-releaseandroid14-mainline-media-swcodec-releaseandroid14-mainline-media-releaseandroid14-mainline-extservices-releaseandroid14-mainline-conscrypt-releaseandroid14-mainline-cellbroadcast-releaseandroid14-mainline-art-releaseandroid14-mainline-appsearch-releaseandroid14-mainline-adservices-releaseandroid14-mainline-adbd-release
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/modules/ImsMedia/+/22582717
Change-Id: I0d172a4c5587fbb3b19c5d9f2079e91afd7b1018
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
6 files changed, 167 insertions, 324 deletions
diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/video/nodes/IVideoRendererNode.h b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/video/nodes/IVideoRendererNode.h index caa54322..3e4483e7 100644 --- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/video/nodes/IVideoRendererNode.h +++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/video/nodes/IVideoRendererNode.h @@ -29,6 +29,16 @@ #define USE_JITTER_BUFFER // off this definition ONLY for test purpose. #define DEMON_NTP2MSEC 65.55 +enum FrameType +{ + UNKNOWN, + SPS, + PPS, + VPS, + IDR, + NonIDR, +}; + /** * @brief This class describes an interface between depacketization module and audio device */ @@ -69,25 +79,25 @@ public: void SetPacketLossParam(uint32_t time, uint32_t rate); private: - bool IsIntraFrame(uint8_t* pbBuffer, uint32_t nBufferSize); - bool IsConfigFrame(uint8_t* pbBuffer, uint32_t nBufferSize, uint32_t* nBufferOffset = nullptr); - bool IsSps(uint8_t* pbBuffer, uint32_t nBufferSize, uint32_t* nBufferOffset = nullptr); - void SaveConfigFrame(uint8_t* pbBuffer, uint32_t nBufferSize, uint32_t type); + bool hasStartingCode(uint8_t* buffer, uint32_t bufferSize); + FrameType GetFrameType(uint8_t* buffer, uint32_t bufferSize); + void SaveConfigFrame(uint8_t* buffer, uint32_t bufferSize, uint32_t type); + /** * @brief Remove Access Uint Delimiter Nal Unit. * - * @param pInBuffer - * @param nInBufferSize - * @param pOutBuffer - * @param pOutBufferSize + * @param inBuffer + * @param ibufferSize + * @param outBuffer + * @param outBufferSize * @return true * @return false */ - bool RemoveAUDNalUnit(uint8_t* pInBuffer, uint32_t nInBufferSize, uint8_t** pOutBuffer, - uint32_t* pOutBufferSize); + bool RemoveAUDNalUnit( + uint8_t* inBuffer, uint32_t ibufferSize, uint8_t** outBuffer, uint32_t* outBufferSize); void CheckResolution(uint32_t nWidth, uint32_t nHeight); - ImsMediaResult ParseAvcSps(uint8_t* pbBuffer, uint32_t nBufferSize, tCodecConfig* pInfo); - ImsMediaResult ParseHevcSps(uint8_t* pbBuffer, uint32_t nBufferSize, tCodecConfig* pInfo); + ImsMediaResult ParseAvcSps(uint8_t* buffer, uint32_t bufferSize, tCodecConfig* config); + ImsMediaResult ParseHevcSps(uint8_t* buffer, uint32_t bufferSize, tCodecConfig* config); void QueueConfigFrame(uint32_t timestamp); void NotifyPeerDimensionChanged(); @@ -107,7 +117,6 @@ private: bool mFirstFrame; ImsMediaSubType mSubtype; uint32_t mFramerate; - uint32_t mWaitIntraFrame; uint32_t mLossDuration; uint32_t mLossRateThreshold; }; diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/nodes/RtpEncoderNode.cpp b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/nodes/RtpEncoderNode.cpp index 40f3d1af..cd4ca421 100644 --- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/nodes/RtpEncoderNode.cpp +++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/nodes/RtpEncoderNode.cpp @@ -290,7 +290,7 @@ bool RtpEncoderNode::SetCvoExtension(const int64_t facing, const int64_t orienta IMLOGD3("[SetCvoExtension] cvoValue[%d], facing[%ld], orientation[%ld]", mCvoValue, facing, orientation); - if (mCvoValue != -1) + if (mCvoValue > 0) { uint32_t rotation = 0; uint32_t cameraId = 0; diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/ImsMediaVideoUtil.cpp b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/ImsMediaVideoUtil.cpp index 817a1153..4dea4783 100644 --- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/ImsMediaVideoUtil.cpp +++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/ImsMediaVideoUtil.cpp @@ -590,22 +590,20 @@ bool ImsMediaVideoUtil::ParseHevcSps(uint8_t* pbBuffer, uint32_t nBufferSize, tC ImsMediaBitReader objBitReader; objBitReader.SetBuffer(pbBuffer + nOffset, nBufferSize - nOffset); - objBitReader.Read(4); // sps_video_parameter_set_id; - uint32_t sps_max_sub_layers_minus1 = objBitReader.Read(3); - objBitReader.Read(1); // sps_temporal_id_nesting_flag; + objBitReader.Read(4); // sps_video_parameter_set_id; + uint32_t sps_max_sub_layers_minus1 = objBitReader.Read(3); // 0 + objBitReader.Read(1); // sps_temporal_id_nesting_flag; - /*-----------profile_tier_level start-----------------------*/ - objBitReader.Read(3); // general_profile_spac, general_tier_flag - objBitReader.Read(5); // general_profile_idc + objBitReader.Read(3); // general_profile_spac, general_tier_flag + pInfo->nProfile = objBitReader.Read(5); // general_profile_idc - // skip 13byte - flags, not handle - objBitReader.Read(24); + // skip 10byte - flags, not handle objBitReader.Read(24); objBitReader.Read(24); objBitReader.Read(24); objBitReader.Read(8); - objBitReader.Read(8); // general_level_idc + pInfo->nLevel = objBitReader.Read(8); // general_level_idc uint8_t sub_layer_profile_present_flag[sps_max_sub_layers_minus1]; uint8_t sub_layer_level_present_flag[sps_max_sub_layers_minus1]; @@ -645,19 +643,15 @@ bool ImsMediaVideoUtil::ParseHevcSps(uint8_t* pbBuffer, uint32_t nBufferSize, tC objBitReader.ReadByUEMode(); // sps_seq_parameter_set_id - uint32_t chroma_format_idc; - chroma_format_idc = objBitReader.ReadByUEMode(); + uint32_t chroma_format_idc = objBitReader.ReadByUEMode(); if (chroma_format_idc == 3) { objBitReader.Read(1); // separate_colour_plane_flag } - int32_t pic_width_in_luma_samples = objBitReader.ReadByUEMode(); - int32_t pic_height_in_luma_samples = objBitReader.ReadByUEMode(); - - pInfo->nWidth = pic_width_in_luma_samples; - pInfo->nHeight = pic_height_in_luma_samples; + pInfo->nWidth = objBitReader.ReadByUEMode(); + pInfo->nHeight = objBitReader.ReadByUEMode(); uint8_t conformance_window_flag = objBitReader.Read(1); diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/android/ImsMediaVideoRenderer.cpp b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/android/ImsMediaVideoRenderer.cpp index a4fe774d..475425be 100644 --- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/android/ImsMediaVideoRenderer.cpp +++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/android/ImsMediaVideoRenderer.cpp @@ -210,10 +210,12 @@ void ImsMediaVideoRenderer::processBuffers() } auto index = AMediaCodec_dequeueInputBuffer(mCodec, CODEC_TIMEOUT_NANO); + if (index >= 0) { size_t bufferSize = 0; uint8_t* inputBuffer = AMediaCodec_getInputBuffer(mCodec, index, &bufferSize); + if (inputBuffer != nullptr) { FrameData* frame = mFrameDatas.front(); @@ -223,17 +225,8 @@ void ImsMediaVideoRenderer::processBuffers() "config[%d]", index, frame->size, frame->timestamp, frame->isConfig); - media_status_t err; - if (frame->isConfig) - { - err = AMediaCodec_queueInputBuffer(mCodec, index, 0, frame->size, - frame->timestamp * 1000, AMEDIACODEC_BUFFER_FLAG_CODEC_CONFIG); - } - else - { - err = AMediaCodec_queueInputBuffer( - mCodec, index, 0, frame->size, frame->timestamp * 1000, 0); - } + media_status_t err = AMediaCodec_queueInputBuffer( + mCodec, index, 0, frame->size, frame->timestamp * 1000, 0); if (err != AMEDIA_OK) { diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/nodes/IVideoRendererNode.cpp b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/nodes/IVideoRendererNode.cpp index 0f5a158f..9cff5794 100644 --- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/nodes/IVideoRendererNode.cpp +++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/nodes/IVideoRendererNode.cpp @@ -53,7 +53,6 @@ IVideoRendererNode::IVideoRendererNode(BaseSessionCallback* callback) : mFirstFrame = false; mSubtype = MEDIASUBTYPE_UNDEFINED; mFramerate = 0; - mWaitIntraFrame = 0; mLossDuration = 0; mLossRateThreshold = 0; } @@ -162,132 +161,103 @@ bool IVideoRendererNode::IsSameConfig(void* config) void IVideoRendererNode::ProcessData() { std::lock_guard<std::mutex> guard(mMutex); - uint8_t* pData = nullptr; - uint32_t nDataSize = 0; - uint32_t nTimeStamp = 0; - bool bMark = false; - uint32_t nSeqNum = 0; + uint8_t* data = nullptr; + uint32_t dataSize = 0; + uint32_t prevTimestamp = 0; + bool mark = false; + uint32_t seq = 0; uint32_t timestamp = 0; - uint32_t nBitstreamSize = 0; + uint32_t frameSize = 0; ImsMediaSubType subtype = MEDIASUBTYPE_UNDEFINED; - uint32_t nInitialSeqNum = 0; - uint32_t nBufferOffset = 0; + uint32_t initialSeq = 0; ImsMediaSubType dataType; - while (GetData(&subtype, &pData, &nDataSize, &nTimeStamp, &bMark, &nSeqNum, &dataType)) + while (GetData(&subtype, &data, &dataSize, ×tamp, &mark, &seq, &dataType)) { IMLOGD_PACKET4(IM_PACKET_LOG_VIDEO, - "[ProcessData] subtype[%d], Size[%d], TimeStamp[%d] nBitstreamSize[%d]", subtype, - nDataSize, nTimeStamp, nBitstreamSize); + "[ProcessData] subtype[%d], Size[%d], TS[%d] frameSize[%d]", subtype, dataSize, + timestamp, frameSize); - if (timestamp == 0) + if (prevTimestamp == 0) { - timestamp = nTimeStamp; + prevTimestamp = timestamp; } - else if (timestamp != nTimeStamp) + else if (timestamp != prevTimestamp || (frameSize != 0 && hasStartingCode(data, dataSize))) { + // break when the timestamp is changed or next data has another starting code break; } - if (nDataSize >= MAX_RTP_PAYLOAD_BUFFER_SIZE) + if (dataSize >= MAX_RTP_PAYLOAD_BUFFER_SIZE) { - IMLOGE1("[ProcessData] exceed buffer size[%d]", nDataSize); + IMLOGE1("[ProcessData] exceed buffer size[%d]", dataSize); return; } - memcpy(mBuffer + nBitstreamSize, pData, nDataSize); - nBitstreamSize += nDataSize; + memcpy(mBuffer + frameSize, data, dataSize); + frameSize += dataSize; - if (nInitialSeqNum == 0) + if (initialSeq == 0) { - nInitialSeqNum = nSeqNum; + initialSeq = seq; } DeleteData(); - if (bMark) + if (mark) { break; } } - if (nBitstreamSize == 0) + if (frameSize == 0) { return; } // remove AUD nal unit - uint32_t nDatabufferSize = nBitstreamSize; - uint8_t* pDataBuff = mBuffer; - RemoveAUDNalUnit(mBuffer, nBitstreamSize, &pDataBuff, &nDatabufferSize); - - // check Config String for updating config frame - nBufferOffset = 0; - if ((mCodecType == kVideoCodecHevc || mCodecType == kVideoCodecAvc) && - IsConfigFrame(pDataBuff, nDatabufferSize, &nBufferOffset)) - { - SaveConfigFrame(pDataBuff + nBufferOffset, nDatabufferSize - nBufferOffset, kConfigSps); - SaveConfigFrame(pDataBuff + nBufferOffset, nDatabufferSize - nBufferOffset, kConfigPps); + uint32_t size = frameSize; + uint8_t* buffer = mBuffer; + RemoveAUDNalUnit(mBuffer, frameSize, &buffer, &size); - if (mCodecType == kVideoCodecHevc) - { - SaveConfigFrame(pDataBuff + nBufferOffset, nDatabufferSize - nBufferOffset, kConfigVps); - } + FrameType frameType = GetFrameType(buffer, size); - if (IsSps(pDataBuff, nDatabufferSize, &nBufferOffset)) - { - IMLOGD_PACKET1( - IM_PACKET_LOG_VIDEO, "[ProcessData] parse SPS - nOffset[%d]", nBufferOffset); - tCodecConfig codecConfig; + if (frameType == SPS) + { + SaveConfigFrame(buffer, size, kConfigSps); + tCodecConfig codecConfig; - if (mCodecType == kVideoCodecAvc) + if (mCodecType == kVideoCodecAvc) + { + if (ImsMediaVideoUtil::ParseAvcSps(buffer, size, &codecConfig)) { - if (ImsMediaVideoUtil::ParseAvcSps(pDataBuff + nBufferOffset, - nDatabufferSize - nBufferOffset, &codecConfig)) - { - CheckResolution(codecConfig.nWidth, codecConfig.nHeight); - } + CheckResolution(codecConfig.nWidth, codecConfig.nHeight); } - else if (mCodecType == kVideoCodecHevc) + } + else if (mCodecType == kVideoCodecHevc) + { + if (ImsMediaVideoUtil::ParseHevcSps(buffer, size, &codecConfig)) { - if (ImsMediaVideoUtil::ParseHevcSps(pDataBuff + nBufferOffset, - nDatabufferSize - nBufferOffset, &codecConfig)) - { - CheckResolution(codecConfig.nWidth, codecConfig.nHeight); - } + CheckResolution(codecConfig.nWidth, codecConfig.nHeight); } } return; } - - IMLOGD_PACKET2(IM_PACKET_LOG_VIDEO, "[ProcessData] nBitstreamSize[%d] nDatabufferSize[%d]", - nBitstreamSize, nDatabufferSize); - - bool isIntraFrame = IsIntraFrame(pDataBuff, nDatabufferSize); - - // drop non-idr frame when idr frame is not received - if (mWaitIntraFrame > 0 && nDatabufferSize > 0) + else if (frameType == PPS) { - if (isIntraFrame) - { - mWaitIntraFrame = 0; - } - else - { - // Send FIR when I-frame wasn't received - if ((mWaitIntraFrame % mFramerate) == 0) // every 1 sec - { - // TODO: send PLI event - IMLOGD0("[ProcessData] request Send PLI"); - } + SaveConfigFrame(buffer, size, kConfigPps); + return; + } + else if (frameType == VPS) + { + SaveConfigFrame(buffer, size, kConfigVps); + return; + } - mWaitIntraFrame--; - nDatabufferSize = 0; // drop non-DIR frame + IMLOGD_PACKET2(IM_PACKET_LOG_VIDEO, "[ProcessData] frame type[%d] size[%d]", frameType, size); - IMLOGD1("[ProcessData] wait intra frame[%d]", mWaitIntraFrame); - } - } + // TODO: Send PLI or FIR when I-frame wasn't received since beginning. if (!mFirstFrame) { @@ -297,6 +267,11 @@ void IVideoRendererNode::ProcessData() if (mCallback != nullptr) { mCallback->SendEvent(kImsMediaEventFirstPacketReceived); + + if (mCvoValue <= 0) + { + mCallback->SendEvent(kImsMediaEventResolutionChanged, mWidth, mHeight); + } } } @@ -336,13 +311,13 @@ void IVideoRendererNode::ProcessData() } } - // send sps/pps before send I frame - if (isIntraFrame) + // send config frames before send I frame + if (frameType == IDR) { QueueConfigFrame(timestamp); } - mVideoRenderer->OnDataFrame(pDataBuff, nDatabufferSize, timestamp, false); + mVideoRenderer->OnDataFrame(buffer, size, timestamp, false); } void IVideoRendererNode::UpdateSurface(ANativeWindow* window) @@ -372,214 +347,84 @@ void IVideoRendererNode::SetPacketLossParam(uint32_t time, uint32_t rate) mLossRateThreshold = rate; } -bool IVideoRendererNode::IsIntraFrame(uint8_t* pbBuffer, uint32_t nBufferSize) +bool IVideoRendererNode::hasStartingCode(uint8_t* buffer, uint32_t bufferSize) { - bool bIntraFrame = false; - - if (nBufferSize <= 4) + if (bufferSize <= 4) { return false; } - IMLOGD_PACKET2(IM_PACKET_LOG_VIDEO, "[IsIntraFrame] size[%d], data[%s]", nBufferSize, - ImsMediaTrace::IMTrace_Bin2String( - reinterpret_cast<const char*>(pbBuffer), nBufferSize > 16 ? 16 : nBufferSize)); - - switch (mCodecType) + // Check for NAL unit delimiter 0x00000001 + if (buffer[0] == 0x00 && buffer[1] == 0x00 && buffer[2] == 0x00 && buffer[3] == 0x01) { - case kVideoCodecAvc: - { - uint32_t nCurrSize = nBufferSize; - uint8_t* nCurrBuff = pbBuffer; - - while (nCurrSize >= 5) - { - if (nCurrBuff[0] == 0x00 && nCurrBuff[1] == 0x00 && nCurrBuff[2] == 0x00 && - nCurrBuff[3] == 0x01 && (nCurrBuff[4] & 0x1F) == 5) - { - bIntraFrame = true; - break; - } - nCurrBuff++; - nCurrSize--; - } - - break; - } - case kVideoCodecHevc: - { - uint32_t nCurrSize = nBufferSize; - uint8_t* nCurrBuff = pbBuffer; - while (nCurrSize >= 5) - { - if (nCurrBuff[0] == 0x00 && nCurrBuff[1] == 0x00 && nCurrBuff[2] == 0x00 && - nCurrBuff[3] == 0x01 && - (((nCurrBuff[4] >> 1) & 0x3F) == 19 || ((nCurrBuff[4] >> 1) & 0x3F) == 20)) - { - bIntraFrame = true; - break; - } - nCurrBuff++; - nCurrSize--; - } - break; - } - default: - IMLOGE1("[IsIntraFrame] Invalid video codec type %d", mCodecType); - return true; + return true; } - return bIntraFrame; + return false; } -bool IVideoRendererNode::IsConfigFrame( - uint8_t* pbBuffer, uint32_t nBufferSize, uint32_t* nBufferOffset) +FrameType IVideoRendererNode::GetFrameType(uint8_t* buffer, uint32_t bufferSize) { - bool bConfigFrame = false; - - if (nBufferSize <= 4) - return false; + if (!hasStartingCode(buffer, bufferSize)) + { + return UNKNOWN; + } - IMLOGD_PACKET2(IM_PACKET_LOG_VIDEO, "[IsConfigFrame] size[%d], data[%s]", nBufferSize, - ImsMediaTrace::IMTrace_Bin2String( - reinterpret_cast<const char*>(pbBuffer), nBufferSize > 16 ? 16 : nBufferSize)); + uint8_t nalType = buffer[4]; switch (mCodecType) { case kVideoCodecAvc: { - uint32_t nOffset = 0; - uint32_t nCurrSize = nBufferSize; - uint8_t* nCurrBuff = pbBuffer; - - while (nCurrSize >= 5) + if ((nalType & 0x1F) == 5) { - if (nCurrBuff[0] == 0x00 && nCurrBuff[1] == 0x00 && nCurrBuff[2] == 0x00 && - nCurrBuff[3] == 0x01 && - ((nCurrBuff[4] & 0x1F) == 7 || ((nCurrBuff[4] & 0x1F) == 8))) - { - bConfigFrame = true; - - if (nBufferOffset) - { - *nBufferOffset = nOffset; - } - break; - } - - nOffset++; - nCurrBuff++; - nCurrSize--; + return IDR; } - break; - } - case kVideoCodecHevc: - { - uint32_t nOffset = 0; - uint32_t nCurrSize = nBufferSize; - uint8_t* nCurrBuff = pbBuffer; - - while (nCurrSize >= 5) + else if ((nalType & 0x1F) == 7) { - if (nCurrBuff[0] == 0x00 && nCurrBuff[1] == 0x00 && nCurrBuff[2] == 0x00 && - nCurrBuff[3] == 0x01 && - (((nCurrBuff[4] >> 1) & 0x3F) == 32 || ((nCurrBuff[4] >> 1) & 0x3F) == 33 || - ((nCurrBuff[4] >> 1) & 0x3F) == 34)) - { - bConfigFrame = true; - if (nBufferOffset) - { - *nBufferOffset = nOffset; - } - break; - } - nOffset++; - nCurrBuff++; - nCurrSize--; + return SPS; } - break; - } - default: - return false; - } - - return bConfigFrame; -} - -bool IVideoRendererNode::IsSps(uint8_t* pbBuffer, uint32_t nBufferSize, uint32_t* nBufferOffset) -{ - bool bSPS = false; - if (nBufferSize <= 4) - { - return false; - } - - IMLOGD_PACKET2(IM_PACKET_LOG_VIDEO, "[IsSps] size[%d], data[%s]", nBufferSize, - ImsMediaTrace::IMTrace_Bin2String( - reinterpret_cast<const char*>(pbBuffer), nBufferSize > 16 ? 16 : nBufferSize)); - - switch (mCodecType) - { - case kVideoCodecAvc: - { - uint32_t nOffset = 0; - uint32_t nCurrSize = nBufferSize; - uint8_t* nCurrBuff = pbBuffer; - - while (nCurrSize >= 5) + else if ((nalType & 0x1F) == 8) { - if (nCurrBuff[0] == 0x00 && nCurrBuff[1] == 0x00 && nCurrBuff[2] == 0x00 && - nCurrBuff[3] == 0x01 && (nCurrBuff[4] & 0x1F) == 7) - { - bSPS = true; - - if (nBufferOffset) - { - *nBufferOffset = nOffset; - } - - break; - } - - nOffset++; - nCurrBuff++; - nCurrSize--; + return PPS; + } + else + { + return NonIDR; } break; } case kVideoCodecHevc: { - uint32_t nOffset = 0; - uint32_t nCurrSize = nBufferSize; - uint8_t* nCurrBuff = pbBuffer; - - while (nCurrSize >= 5) + if (((nalType >> 1) & 0x3F) == 19 || ((nalType >> 1) & 0x3F) == 20) { - if (nCurrBuff[0] == 0x00 && nCurrBuff[1] == 0x00 && nCurrBuff[2] == 0x00 && - nCurrBuff[3] == 0x01 && ((nCurrBuff[4] >> 1) & 0x3F) == 33) - { - bSPS = true; - - if (nBufferOffset) - { - *nBufferOffset = nOffset; - } - - break; - } - - nOffset++; - nCurrBuff++; - nCurrSize--; + return IDR; + } + else if (((nalType >> 1) & 0x3F) == 32) + { + return VPS; + } + else if (((nalType >> 1) & 0x3F) == 33) + { + return SPS; } + else if (((nalType >> 1) & 0x3F) == 34) + { + return PPS; + } + else + { + return NonIDR; + } + break; } default: - return false; + IMLOGE1("[GetFrameType] Invalid video codec type %d", mCodecType); } - return bSPS; + return UNKNOWN; } void IVideoRendererNode::SaveConfigFrame(uint8_t* pbBuffer, uint32_t nBufferSize, uint32_t eMode) @@ -761,13 +606,13 @@ void IVideoRendererNode::SaveConfigFrame(uint8_t* pbBuffer, uint32_t nBufferSize } bool IVideoRendererNode::RemoveAUDNalUnit( - uint8_t* pInBuffer, uint32_t nInBufferSize, uint8_t** ppOutBuffer, uint32_t* pOutBufferSize) + uint8_t* inBuffer, uint32_t inBufferSize, uint8_t** outBuffer, uint32_t* outBufferSize) { - bool bAUDUnit = false; - *ppOutBuffer = pInBuffer; - *pOutBufferSize = nInBufferSize; + bool IsAudUnit = false; + *outBuffer = inBuffer; + *outBufferSize = inBufferSize; - if (nInBufferSize <= 4) + if (inBufferSize <= 4) { return false; } @@ -776,29 +621,29 @@ bool IVideoRendererNode::RemoveAUDNalUnit( { case kVideoCodecAvc: { - uint32_t nCurrSize = nInBufferSize; - uint8_t* nCurrBuff = pInBuffer; - uint32_t nCnt = 0; + uint32_t currSize = inBufferSize; + uint8_t* currBuffer = inBuffer; + uint32_t count = 0; - while (nCurrSize >= 5 && nCnt <= 12) + while (currSize >= 5 && count <= 12) { - if (bAUDUnit && - (nCurrBuff[0] == 0x00 && nCurrBuff[1] == 0x00 && nCurrBuff[2] == 0x00 && - nCurrBuff[3] == 0x01)) + if (IsAudUnit && + (currBuffer[0] == 0x00 && currBuffer[1] == 0x00 && currBuffer[2] == 0x00 && + currBuffer[3] == 0x01)) { - *ppOutBuffer = nCurrBuff; - *pOutBufferSize = nCurrSize; + *outBuffer = currBuffer; + *outBufferSize = currSize; break; } - if (nCurrBuff[0] == 0x00 && nCurrBuff[1] == 0x00 && nCurrBuff[2] == 0x00 && - nCurrBuff[3] == 0x01 && nCurrBuff[4] == 0x09) + if (currBuffer[0] == 0x00 && currBuffer[1] == 0x00 && currBuffer[2] == 0x00 && + currBuffer[3] == 0x01 && currBuffer[4] == 0x09) { - bAUDUnit = true; + IsAudUnit = true; } - nCurrBuff++; - nCurrSize--; - nCnt++; + currBuffer++; + currSize--; + count++; } } break; @@ -807,7 +652,7 @@ bool IVideoRendererNode::RemoveAUDNalUnit( return false; } - return bAUDUnit; + return IsAudUnit; } void IVideoRendererNode::CheckResolution(uint32_t nWidth, uint32_t nHeight) @@ -837,16 +682,16 @@ void IVideoRendererNode::QueueConfigFrame(uint32_t timestamp) for (int32_t i = 0; i < nNumOfConfigString; i++) { - uint8_t* pConfigData = nullptr; - uint32_t nConfigLen = mConfigLen[i]; - pConfigData = mConfigBuffer[i]; + uint8_t* configFrame = nullptr; + uint32_t configLen = mConfigLen[i]; + configFrame = mConfigBuffer[i]; - if (nConfigLen == 0 || mVideoRenderer == nullptr) + if (configLen == 0 || mVideoRenderer == nullptr) { continue; } - mVideoRenderer->OnDataFrame(pConfigData, nConfigLen, timestamp, true); + mVideoRenderer->OnDataFrame(configFrame, configLen, timestamp, true); } } @@ -857,6 +702,8 @@ void IVideoRendererNode::NotifyPeerDimensionChanged() return; } + IMLOGD1("[NotifyPeerDimensionChanged] subtype[%d]", mSubtype); + // assume the device is portrait if (mWidth > mHeight) // landscape { diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/nodes/VideoRtpPayloadEncoderNode.cpp b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/nodes/VideoRtpPayloadEncoderNode.cpp index 6ec6a3cd..e601c16c 100644 --- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/nodes/VideoRtpPayloadEncoderNode.cpp +++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/nodes/VideoRtpPayloadEncoderNode.cpp @@ -502,7 +502,7 @@ void VideoRtpPayloadEncoderNode::EncodeHevc( memset(mPPS, 0, MAX_CONFIG_LEN); memcpy(mPPS, pCurDataPos, nCurDataSize); mPpsSize = nCurDataSize; - IMLOGD1("[EncodeHevc] PPS Size [%d]", mSpsSize); + IMLOGD1("[EncodeHevc] PPS Size [%d]", mPpsSize); } if (nDataSize < nCurDataSize + 4) |