From e8010bc676967fffea7e9d751e39fddc96544aee Mon Sep 17 00:00:00 2001 From: bodamnam Date: Mon, 6 Feb 2023 08:28:57 +0000 Subject: Fix the notificaiton of mediaQualityStatus repeated after expired issue Fix not to notify mediaQualityStatus again once if it is notified during the target parameter inactivity continue Bug: 267981047 Test: atest ImsMediaNativeTests, verified with device testing with TC L_IR94_6864_1 Change-Id: Ib75e5b5345f20fda3d17239d04022a5100bcb563 --- .../imsmedia/lib/libimsmedia/core/audio/MediaQualityAnalyzer.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/MediaQualityAnalyzer.cpp b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/MediaQualityAnalyzer.cpp index f4ef92eb..cd092b8e 100644 --- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/MediaQualityAnalyzer.cpp +++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/MediaQualityAnalyzer.cpp @@ -403,7 +403,7 @@ void MediaQualityAnalyzer::processData(const int32_t timeCount) void MediaQualityAnalyzer::processMediaQuality() { // media quality rtp inactivity - if (!mCurrentRtpInactivityTimes.empty() && mNumRxPacket == 0) + if (mNumRxPacket == 0) { mCountRtpInactivity += 1000; } @@ -415,7 +415,7 @@ void MediaQualityAnalyzer::processMediaQuality() } // media quality rtcp inactivity - if (mRtcpInactivityTime != 0 && mNumRtcpPacketReceived == 0) + if (mNumRtcpPacketReceived == 0) { mCountRtcpInactivity += 1000; } @@ -499,10 +499,10 @@ void MediaQualityAnalyzer::processMediaQuality() } } - if (mRtcpInactivityTime != 0 && mCountRtcpInactivity >= mRtcpInactivityTime) + if (mRtcpInactivityTime != 0 && mCountRtcpInactivity == mRtcpInactivityTime) { notifyMediaQualityStatus(); - mCountRtcpInactivity = 0; // reset + mCountRtcpInactivity = 0; return; } -- cgit v1.2.3 From b1c779b9291172543706b419c8704da727a38e60 Mon Sep 17 00:00:00 2001 From: bodamnam Date: Fri, 3 Feb 2023 04:36:23 +0000 Subject: Fix ImsMediaVideoSource crash in processOutputBuffer 1) Replace the mutex lock to auto lock 2) Skip before processing the uplink frame checking the session stopped 3) Remove use-after-delete memory case in ImsMediaCamera Bug: 259500454 Bug: 259500583 Bug: 265611777 Test: loopback test with ImsMediaTestingApp in hwasan debugging binary, atest ImsMediaNativeTests Change-Id: I667c3277795b734cbce90e41e060536096102288 --- .../core/video/android/ImsMediaCamera.cpp | 10 +++---- .../core/video/android/ImsMediaVideoSource.cpp | 31 +++++++++++----------- .../core/video/VideoStreamGraphRtpTxTest.cpp | 7 ----- 3 files changed, 20 insertions(+), 28 deletions(-) diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/android/ImsMediaCamera.cpp b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/android/ImsMediaCamera.cpp index d2fa1e8b..36a4f1eb 100644 --- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/android/ImsMediaCamera.cpp +++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/android/ImsMediaCamera.cpp @@ -725,12 +725,11 @@ void ImsMediaCamera::EnumerateCamera() bool ImsMediaCamera::GetSensorOrientation(const int cameraId, int32_t* facing, int32_t* angle) { - if (!mManager) + if (!mManager || facing == nullptr || angle == nullptr) { return false; } - camera_status_t status; ACameraMetadata* metadataObj; uint32_t idx = 0; @@ -739,8 +738,8 @@ bool ImsMediaCamera::GetSensorOrientation(const int cameraId, int32_t* facing, i { if (idx == cameraId) { - status = ACameraManager_getCameraCharacteristics( - mManager, gCameraIds[(it->second).mId].mId.c_str(), &metadataObj); + camera_status_t status = ACameraManager_getCameraCharacteristics( + mManager, (it->second).mId.c_str(), &metadataObj); if (status == ACAMERA_OK) { ACameraMetadata_const_entry face, orientation; @@ -748,11 +747,10 @@ bool ImsMediaCamera::GetSensorOrientation(const int cameraId, int32_t* facing, i mCameraFacing = static_cast(face.data.u8[0]); ACameraMetadata_getConstEntry( metadataObj, ACAMERA_SENSOR_ORIENTATION, &orientation); - ACameraMetadata_free(metadataObj); mCameraOrientation = orientation.data.i32[0]; - mCameraFacing == 0 ? * facing = kCameraFacingFront : * facing = kCameraFacingRear; *angle = mCameraOrientation; + ACameraMetadata_free(metadataObj); return true; } } diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/android/ImsMediaVideoSource.cpp b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/android/ImsMediaVideoSource.cpp index ce4bc83d..c93d99a4 100644 --- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/android/ImsMediaVideoSource.cpp +++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/android/ImsMediaVideoSource.cpp @@ -334,7 +334,11 @@ void ImsMediaVideoSource::Stop() if (mCodec != nullptr) { - AMediaCodec_signalEndOfInputStream(mCodec); + if (mRecordingSurface != nullptr) + { + AMediaCodec_signalEndOfInputStream(mCodec); + } + AMediaCodec_stop(mCodec); if (mRecordingSurface != nullptr) @@ -511,21 +515,16 @@ void ImsMediaVideoSource::processOutputBuffer() timeInterval = 1000 / mFramerate; } - IMLOGD2("[processOutputBuffer] interval[%d] mCameraId[%d]", timeInterval, mCameraId); + IMLOGD2("[processOutputBuffer] interval[%d] CameraId[%d]", timeInterval, mCameraId); for (;;) { - uint32_t nCurrTime; - mMutex.lock(); - - if (mStopped) + if (IsStopped()) { IMLOGD0("[processOutputBuffer] terminated"); - mMutex.unlock(); break; } - mMutex.unlock(); if (mVideoMode == kVideoModePauseImage) { EncodePauseImage(); @@ -545,6 +544,11 @@ void ImsMediaVideoSource::processOutputBuffer() size_t buffCapacity; uint8_t* buf = AMediaCodec_getOutputBuffer(mCodec, index, &buffCapacity); + if (IsStopped()) + { + break; + } + if (buf != nullptr && buffCapacity > 0) { if (mListener != nullptr) @@ -553,16 +557,13 @@ void ImsMediaVideoSource::processOutputBuffer() buf + info.offset, info.size, info.presentationTimeUs, info.flags); } } - } - if (!IsStopped()) - { AMediaCodec_releaseOutputBuffer(mCodec, index, false); } } else if (index == AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED) { - IMLOGD0("[processOutputBuffer] Encoder output buffer changed"); + IMLOGI0("[processOutputBuffer] Encoder output buffer changed"); } else if (index == AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED) { @@ -572,7 +573,7 @@ void ImsMediaVideoSource::processOutputBuffer() } mFormat = AMediaCodec_getOutputFormat(mCodec); - IMLOGD1("[processOutputBuffer] Encoder format changed, format[%s]", + IMLOGI1("[processOutputBuffer] Encoder format changed, format[%s]", AMediaFormat_toString(mFormat)); } else if (index == AMEDIACODEC_INFO_TRY_AGAIN_LATER) @@ -581,11 +582,11 @@ void ImsMediaVideoSource::processOutputBuffer() } else { - IMLOGD1("[processOutputBuffer] unexpected index[%d]", index); + IMLOGI1("[processOutputBuffer] unexpected index[%d]", index); } nextTime += timeInterval; - nCurrTime = ImsMediaTimer::GetTimeInMilliSeconds(); + uint32_t nCurrTime = ImsMediaTimer::GetTimeInMilliSeconds(); if (nextTime > nCurrTime) { diff --git a/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/VideoStreamGraphRtpTxTest.cpp b/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/VideoStreamGraphRtpTxTest.cpp index 281410e9..332041c4 100644 --- a/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/VideoStreamGraphRtpTxTest.cpp +++ b/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/video/VideoStreamGraphRtpTxTest.cpp @@ -123,13 +123,6 @@ protected: 1, &previewReader), AMEDIA_OK); AImageReader_getWindow(previewReader, &previewSurface); - - /* - * TODO: Below line will skip all test under this class, need to remove - * to include it in atets - */ - - GTEST_SKIP(); } virtual void TearDown() override -- cgit v1.2.3 From a2780ec8c9453b2d140611eabe30f5b2835a70f1 Mon Sep 17 00:00:00 2001 From: dhavalc Date: Tue, 7 Feb 2023 07:21:49 +0000 Subject: Removed conversion from bits to bytes to make compressed size consistent with soft codec and Aoc codec Fix: 268145414 Test: Tested with soft codec as well as Aoc and audio is proper. Change-Id: Ib22c5794f2aa55f6a0b4a3ace12a2b00e5158197 --- .../lib/libimsmedia/core/audio/nodes/AudioRtpPayloadEncoderNode.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/nodes/AudioRtpPayloadEncoderNode.cpp b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/nodes/AudioRtpPayloadEncoderNode.cpp index 547f65ef..028eba2d 100644 --- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/nodes/AudioRtpPayloadEncoderNode.cpp +++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/nodes/AudioRtpPayloadEncoderNode.cpp @@ -280,9 +280,6 @@ void AudioRtpPayloadEncoderNode::EncodePayloadEvs( kRtpPyaloadHeaderMode eEVSPayloadFormat = kRtpPyaloadHeaderModeEvsHeaderFull; kEvsCodecMode kEvsCodecMode; - // Converting bits to bytes. - nDataSize /= 8; - // 0111 1111 is no request. uint32_t nEVSBW = 0x07; uint32_t nEVSBR = 0x0f; -- cgit v1.2.3 From 527e04afac23dcebce6fc91ad11a6a48817048e6 Mon Sep 17 00:00:00 2001 From: bodamnam Date: Wed, 8 Feb 2023 01:55:00 +0000 Subject: Fix the crash in SendRtcpXr 1) Add inialization of the rtcpxr payload array 2) Add statement to return false when the report block is not supported Bug: 268171537 Test: loopback test with ImsMediaTestingApp, atest ImsMediaNativeTests Change-Id: I6590ec7ab69e6b1aaca2c653aaba1e231eb39aa2 --- .../imsmedia/lib/libimsmedia/core/audio/MediaQualityAnalyzer.cpp | 8 ++++---- .../imsmedia/lib/libimsmedia/core/audio/RtcpXrEncoder.cpp | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/MediaQualityAnalyzer.cpp b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/MediaQualityAnalyzer.cpp index f4ef92eb..d67e0b0c 100644 --- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/MediaQualityAnalyzer.cpp +++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/MediaQualityAnalyzer.cpp @@ -545,10 +545,10 @@ bool MediaQualityAnalyzer::getRtcpXrReportBlock( return false; } - if (mRtcpXrEncoder->createRtcpXrReport(rtcpXrReport, &mListRxPacket, &mListLostPacket, - mBeginSeq, mEndSeq, data, size) == false) + if (!mRtcpXrEncoder->createRtcpXrReport( + rtcpXrReport, &mListRxPacket, &mListLostPacket, mBeginSeq, mEndSeq, data, size)) { - IMLOGE0("[getRtcpXrReportBlock] error createRtcpXrReport"); + IMLOGW0("[getRtcpXrReportBlock] fail to createRtcpXrReport"); return false; } @@ -629,7 +629,7 @@ void MediaQualityAnalyzer::processEvent(uint32_t event, uint64_t paramA, uint64_ case kGetRtcpXrReportBlock: { uint32_t size = 0; - uint8_t* reportBlock = new uint8_t[MAX_BLOCK_LENGTH]; + uint8_t* reportBlock = new uint8_t[MAX_BLOCK_LENGTH]{}; if (getRtcpXrReportBlock(static_cast(paramA), reportBlock, size)) { diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/RtcpXrEncoder.cpp b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/RtcpXrEncoder.cpp index d30ea331..3bc108d4 100644 --- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/RtcpXrEncoder.cpp +++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/RtcpXrEncoder.cpp @@ -196,7 +196,8 @@ bool RtcpXrEncoder::createRtcpXrReport(const uint32_t rtcpXrReport, std::list 0); } tLossReport* RtcpXrEncoder::createLossAnalysisReport(std::list* packets, -- cgit v1.2.3 From f5093cd628b7308a28e890918e5453408d9f140a Mon Sep 17 00:00:00 2001 From: bodamnam Date: Fri, 13 Jan 2023 09:45:26 +0000 Subject: Fix to increase the dtmf payload timestamp 1) Fix to use increasing timestamp for dtmf frame in the RtpEncoderNode 2) DtmfSenderNode operates asynchronous thread operation to keep the constant interval, but it is already done in RtpEncoderNode, so I removed the node. Bug: 264831620 Test: loopback test in ImsMediaTestingApp, atest ImsMediaNativeTests, Verified by ATT LTE_BTR_5_5466 case passed. Change-Id: I6027007cfd3e09a541316197566f8724c0b7ca3a --- .../core/audio/AudioStreamGraphRtpTx.cpp | 10 +- .../core/audio/nodes/DtmfSenderNode.cpp | 128 --------------------- .../core/include/audio/AudioStreamGraphRtpTx.h | 2 +- .../core/include/audio/nodes/DtmfSenderNode.h | 43 ------- .../lib/libimsmedia/core/include/nodes/BaseNode.h | 1 - .../core/include/nodes/RtpEncoderNode.h | 4 +- .../lib/libimsmedia/core/nodes/BaseNode.cpp | 1 - .../lib/libimsmedia/core/nodes/RtpEncoderNode.cpp | 34 ++---- 8 files changed, 14 insertions(+), 209 deletions(-) delete mode 100644 service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/nodes/DtmfSenderNode.cpp delete mode 100644 service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/audio/nodes/DtmfSenderNode.h diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/AudioStreamGraphRtpTx.cpp b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/AudioStreamGraphRtpTx.cpp index 372a137d..3444ab43 100644 --- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/AudioStreamGraphRtpTx.cpp +++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/AudioStreamGraphRtpTx.cpp @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -175,16 +174,9 @@ bool AudioStreamGraphRtpTx::createDtmfGraph(RtpConfig* config, BaseNode* rtpEnco AddNode(pDtmfEncoderNode); mListDtmfNodes.push_back(pDtmfEncoderNode); - BaseNode* pDtmfSenderNode = new DtmfSenderNode(mCallback); - pDtmfSenderNode->SetMediaType(IMS_MEDIA_AUDIO); - pDtmfSenderNode->SetConfig(audioConfig); - pDtmfEncoderNode->ConnectRearNode(pDtmfSenderNode); - AddNode(pDtmfSenderNode); - mListDtmfNodes.push_back(pDtmfSenderNode); - if (rtpEncoderNode != nullptr) { - pDtmfSenderNode->ConnectRearNode(rtpEncoderNode); + pDtmfEncoderNode->ConnectRearNode(rtpEncoderNode); } return true; diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/nodes/DtmfSenderNode.cpp b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/nodes/DtmfSenderNode.cpp deleted file mode 100644 index d0c75835..00000000 --- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/nodes/DtmfSenderNode.cpp +++ /dev/null @@ -1,128 +0,0 @@ -/** - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include - -DtmfSenderNode::DtmfSenderNode(BaseSessionCallback* callback) : - BaseNode(callback) -{ - mNextTime = 0; - mPrevTime = 0; - mPtime = 20; -} - -DtmfSenderNode::~DtmfSenderNode() {} - -kBaseNodeId DtmfSenderNode::GetNodeId() -{ - return kNodeIdDtmfSender; -} - -ImsMediaResult DtmfSenderNode::Start() -{ - mNextTime = 0; - mNodeState = kNodeStateRunning; - return RESULT_SUCCESS; -} - -void DtmfSenderNode::Stop() -{ - mNextTime = 0; - ClearDataQueue(); - mNodeState = kNodeStateStopped; -} - -bool DtmfSenderNode::IsRunTime() -{ - return false; -} - -bool DtmfSenderNode::IsSourceNode() -{ - return false; -} - -void DtmfSenderNode::SetConfig(void* config) -{ - AudioConfig* pConfig = reinterpret_cast(config); - - if (pConfig != nullptr) - { - mPtime = pConfig->getPtimeMillis(); - } -} - -bool DtmfSenderNode::IsSameConfig(void* config) -{ - if (config == nullptr) - { - return true; - } - - AudioConfig* pConfig = reinterpret_cast(config); - return (mPtime == pConfig->getPtimeMillis()); -} - -void DtmfSenderNode::ProcessData() -{ - ImsMediaSubType subtype; - uint8_t* pData; - uint32_t nDataSize; - uint32_t nTimeStamp; - bool bMark; - uint32_t nCurrTime; - - if (GetData(&subtype, &pData, &nDataSize, &nTimeStamp, &bMark, nullptr) == false) - { - return; - } - - nCurrTime = ImsMediaTimer::GetTimeInMilliSeconds(); - - if (mNextTime && !(nCurrTime >= mNextTime || nCurrTime < mPrevTime || mNextTime < mPrevTime)) - { - mPrevTime = nCurrTime; - return; - } - - if (subtype == MEDIASUBTYPE_DTMFSTART) - { - SendDataToRearNode(subtype, pData, nDataSize, nTimeStamp, bMark, 0); - DeleteData(); - mNextTime = nCurrTime; - - // send the first dtmf packet - if (GetData(&subtype, &pData, &nDataSize, &nTimeStamp, &bMark, nullptr, nullptr) && - subtype == MEDIASUBTYPE_DTMF_PAYLOAD) - { - SendDataToRearNode(subtype, pData, nDataSize, nTimeStamp, bMark, 0); - DeleteData(); - mNextTime += mPtime; - } - } - else - { - SendDataToRearNode(subtype, pData, nDataSize, nTimeStamp, bMark, 0); - DeleteData(); - mNextTime += mPtime; - } - - mPrevTime = nCurrTime; -} diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/audio/AudioStreamGraphRtpTx.h b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/audio/AudioStreamGraphRtpTx.h index 5853de91..c042b7c7 100644 --- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/audio/AudioStreamGraphRtpTx.h +++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/audio/AudioStreamGraphRtpTx.h @@ -33,7 +33,7 @@ public: * * @param config AudioConfig for setting the parameters for nodes * @param rtpEncoderNode The RtpEncoderNode instance to connect as a rear node after the - * DtmfSenderNode, if it is null, no dtmf packet will be delivered to RtpEncoderNode. + * DtmfEncoderNode, if it is null, no dtmf packet will be delivered to RtpEncoderNode. * @return true Returns when the graph created without error * @return false Returns when the given parameters are invalid. */ diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/audio/nodes/DtmfSenderNode.h b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/audio/nodes/DtmfSenderNode.h deleted file mode 100644 index 8956b90b..00000000 --- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/audio/nodes/DtmfSenderNode.h +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef DTMFSENDERNODE_H_INCLUDED -#define DTMFSENDERNODE_H_INCLUDED - -#include -#include - -class DtmfSenderNode : public BaseNode -{ -public: - DtmfSenderNode(BaseSessionCallback* callback = nullptr); - virtual ~DtmfSenderNode(); - virtual kBaseNodeId GetNodeId(); - virtual ImsMediaResult Start(); - virtual void Stop(); - virtual bool IsRunTime(); - virtual bool IsSourceNode(); - virtual void SetConfig(void* config); - virtual bool IsSameConfig(void* config); - virtual void ProcessData(); - -private: - uint32_t mNextTime; - uint32_t mPrevTime; - int8_t mPtime; // msec unit, interval between dtmf packets -}; - -#endif // DTMFSENDERNODE_H_INCLUDED diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/nodes/BaseNode.h b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/nodes/BaseNode.h index 78dde778..360c46bc 100644 --- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/nodes/BaseNode.h +++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/nodes/BaseNode.h @@ -49,7 +49,6 @@ enum kBaseNodeId kNodeIdAudioSource, kNodeIdAudioPlayer, kNodeIdDtmfEncoder, - kNodeIdDtmfSender, kNodeIdAudioPayloadEncoder, kNodeIdAudioPayloadDecoder, // for Video diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/nodes/RtpEncoderNode.h b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/nodes/RtpEncoderNode.h index d134f435..788f227e 100644 --- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/nodes/RtpEncoderNode.h +++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/nodes/RtpEncoderNode.h @@ -58,8 +58,7 @@ public: void SetRtpHeaderExtension(tRtpHeaderExtensionInfo& tExtension); private: - bool ProcessAudioData( - ImsMediaSubType subtype, uint8_t* pData, uint32_t nDataSize, uint32_t timestamp); + bool ProcessAudioData(ImsMediaSubType subtype, uint8_t* pData, uint32_t nDataSize); void ProcessVideoData(ImsMediaSubType subtype, uint8_t* pData, uint32_t nDataSize, uint32_t timestamp, bool mark); void ProcessTextData(ImsMediaSubType subtype, uint8_t* pData, uint32_t nDataSize, @@ -72,7 +71,6 @@ private: bool mDTMFMode; bool mMark; uint32_t mPrevTimestamp; - uint32_t mDTMFTimestamp; int8_t mSamplingRate; int8_t mRtpPayloadTx; int8_t mRtpPayloadRx; diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/nodes/BaseNode.cpp b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/nodes/BaseNode.cpp index 4e29d706..b2fb076f 100644 --- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/nodes/BaseNode.cpp +++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/nodes/BaseNode.cpp @@ -30,7 +30,6 @@ static std::vector vectorNodeId{ std::make_pair(kNodeIdAudioSource, "AudioSource"), std::make_pair(kNodeIdAudioPlayer, "AudioPlayer"), std::make_pair(kNodeIdDtmfEncoder, "DtmfEncoder"), - std::make_pair(kNodeIdDtmfSender, "DtmfSender"), std::make_pair(kNodeIdAudioPayloadEncoder, "AudioPayloadEncoder"), std::make_pair(kNodeIdAudioPayloadDecoder, "AudioPayloadDecoder"), std::make_pair(kNodeIdVideoSource, "VideoSource"), 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 ff45e252..d89d5bed 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 @@ -30,7 +30,6 @@ RtpEncoderNode::RtpEncoderNode(BaseSessionCallback* callback) : mDTMFMode = false; mMark = false; mPrevTimestamp = 0; - mDTMFTimestamp = 0; mSamplingRate = 0; mRtpPayloadTx = 0; mRtpPayloadRx = 0; @@ -108,7 +107,6 @@ ImsMediaResult RtpEncoderNode::Start() mDTMFMode = false; mMark = true; mPrevTimestamp = 0; - mDTMFTimestamp = 0; #ifdef DEBUG_JITTER_GEN_SIMULATION_DELAY mNextTime = 0; #endif @@ -156,7 +154,7 @@ void RtpEncoderNode::ProcessData() { if (mMediaType == IMS_MEDIA_AUDIO) { - if (!ProcessAudioData(subtype, data, size, timestamp)) + if (!ProcessAudioData(subtype, data, size)) { return; } @@ -350,8 +348,7 @@ void RtpEncoderNode::SetRtpHeaderExtension(tRtpHeaderExtensionInfo& tExtension) mRtpExtension = tExtension; } -bool RtpEncoderNode::ProcessAudioData( - ImsMediaSubType subtype, uint8_t* data, uint32_t size, uint32_t timestamp) +bool RtpEncoderNode::ProcessAudioData(ImsMediaSubType subtype, uint8_t* data, uint32_t size) { uint32_t currentTimestamp; uint32_t timeDiff; @@ -373,30 +370,21 @@ bool RtpEncoderNode::ProcessAudioData( { if (mDTMFMode) { - IMLOGD_PACKET2(IM_PACKET_LOG_RTP, "[ProcessAudioData] DTMF - size[%d], TS[%d]", size, - mDTMFTimestamp); - // the first dtmf event - if (timestamp == 0) - { - currentTimestamp = ImsMediaTimer::GetTimeInMilliSeconds(); - mDTMFTimestamp = currentTimestamp; - timeDiff = ((currentTimestamp - mPrevTimestamp) + 10) / 20 * 20; - - if (timeDiff == 0) - { - timeDiff = 20; - } + currentTimestamp = ImsMediaTimer::GetTimeInMilliSeconds(); + timeDiff = currentTimestamp - mPrevTimestamp; - mPrevTimestamp += timeDiff; - } - else + if (timeDiff < 20) { - timeDiff = 0; + return false; } + mPrevTimestamp = currentTimestamp; timestampDiff = timeDiff * mSamplingRate; + + IMLOGD_PACKET2(IM_PACKET_LOG_RTP, "[ProcessAudioData] dtmf payload, size[%u], TS[%u]", + size, currentTimestamp); mRtpSession->SendRtpPacket( - mRtpTxDtmfPayload, data, size, mDTMFTimestamp, mMark, timestampDiff); + mRtpTxDtmfPayload, data, size, currentTimestamp, mMark, timestampDiff); if (mMark) { -- cgit v1.2.3 From aceadd0b885d07f1fb805a8b334c36d466508aa1 Mon Sep 17 00:00:00 2001 From: dhavalc Date: Wed, 1 Feb 2023 09:14:00 +0000 Subject: Added implementation to handle audio media direction on IAudioSource node Fix: 267299910 Test: Tested with hold/unhold cases and direction reflected properly Change-Id: Ifbd6565df26321b5211098b437e20700c0b63a60 --- .../lib/libimsmedia/core/audio/android/ImsMediaAudioSource.cpp | 6 ++++++ .../libimsmedia/core/audio/android/include/ImsMediaAudioSource.h | 8 ++++++++ .../lib/libimsmedia/core/audio/nodes/IAudioSourceNode.cpp | 9 +++++++-- .../lib/libimsmedia/core/include/audio/nodes/IAudioSourceNode.h | 1 + 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/android/ImsMediaAudioSource.cpp b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/android/ImsMediaAudioSource.cpp index 348cd0a3..9117e0ad 100644 --- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/android/ImsMediaAudioSource.cpp +++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/android/ImsMediaAudioSource.cpp @@ -49,6 +49,7 @@ ImsMediaAudioSource::ImsMediaAudioSource() mEvsBitRate = 0; mEvsChAwOffset = 0; mIsEvsInitialized = false; + mMediaDirection = 0; } ImsMediaAudioSource::~ImsMediaAudioSource() {} @@ -98,6 +99,11 @@ void ImsMediaAudioSource::SetEvsBandwidth(int32_t evsBandwidth) mEvsBandwidth = (kEvsBandwidth)evsBandwidth; } +void ImsMediaAudioSource::SetMediaDirection(int32_t direction) +{ + mMediaDirection = direction; +} + bool ImsMediaAudioSource::Start() { char kMimeType[128] = {'\0'}; diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/android/include/ImsMediaAudioSource.h b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/android/include/ImsMediaAudioSource.h index cd484db7..63ed1ad7 100644 --- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/android/include/ImsMediaAudioSource.h +++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/android/include/ImsMediaAudioSource.h @@ -94,6 +94,13 @@ public: */ void SetEvsChAwOffset(int32_t offset); + /** + * @brief Sets audio media direction of the RTP session + * + * @param direction can be NO_FLOW, SEND_ONLY, RECEIVE_ONLY, SEND_RECEIVE, INACTIVE + */ + void SetMediaDirection(int32_t direction); + /** * @brief Starts aaudio and ndk audio codec to get the audio frame and encode the audio frames * with given configuration @@ -141,6 +148,7 @@ private: int32_t mEvsChAwOffset; ImsMediaCondition mConditionExit; bool mIsEvsInitialized; + int32_t mMediaDirection; }; #endif diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/nodes/IAudioSourceNode.cpp b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/nodes/IAudioSourceNode.cpp index 43f09cb7..9e0fe4e0 100644 --- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/nodes/IAudioSourceNode.cpp +++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/nodes/IAudioSourceNode.cpp @@ -32,6 +32,7 @@ IAudioSourceNode::IAudioSourceNode(BaseSessionCallback* callback) : mCodecMode = 0; mRunningCodecMode = 0; mFirstFrame = false; + mMediaDirection = 0; } IAudioSourceNode::~IAudioSourceNode() {} @@ -52,6 +53,7 @@ ImsMediaResult IAudioSourceNode::Start() mRunningCodecMode = ImsMediaAudioUtil::GetMaximumAmrMode(mCodecMode); mAudioSource->SetPtime(mPtime); mAudioSource->SetSamplingRate(mSamplingRate * 1000); + mAudioSource->SetMediaDirection(mMediaDirection); if (mCodecType == kAudioCodecEvs) { @@ -122,6 +124,7 @@ void IAudioSourceNode::SetConfig(void* config) mEvsChAwOffset = pConfig->getEvsParams().getChannelAwareMode(); } + mMediaDirection = pConfig->getMediaDirection(); mSamplingRate = pConfig->getSamplingRateKHz(); mPtime = pConfig->getPtimeMillis(); } @@ -140,7 +143,8 @@ bool IAudioSourceNode::IsSameConfig(void* config) if (mCodecType == kAudioCodecAmr || mCodecType == kAudioCodecAmrWb) { return (mCodecMode == pConfig->getAmrParams().getAmrMode() && - mSamplingRate == pConfig->getSamplingRateKHz()); + mSamplingRate == pConfig->getSamplingRateKHz() && + mMediaDirection == pConfig->getMediaDirection()); } else if (mCodecType == kAudioCodecEvs) { @@ -149,7 +153,8 @@ bool IAudioSourceNode::IsSameConfig(void* config) ImsMediaAudioUtil::FindMaxEvsBandwidthFromRange( pConfig->getEvsParams().getEvsBandwidth()) && mEvsChAwOffset == pConfig->getEvsParams().getChannelAwareMode() && - mSamplingRate == pConfig->getSamplingRateKHz()); + mSamplingRate == pConfig->getSamplingRateKHz() && + mMediaDirection == pConfig->getMediaDirection()); } } diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/audio/nodes/IAudioSourceNode.h b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/audio/nodes/IAudioSourceNode.h index e96ac672..794e655e 100644 --- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/audio/nodes/IAudioSourceNode.h +++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/audio/nodes/IAudioSourceNode.h @@ -66,6 +66,7 @@ public: kEvsBandwidth mEvsBandwidth; int8_t mSamplingRate; int8_t mEvsChAwOffset; + int32_t mMediaDirection; }; #endif -- cgit v1.2.3 From 3a1bf17f69890421dfca05c35cf5a8debcf79c55 Mon Sep 17 00:00:00 2001 From: bodamnam Date: Thu, 15 Dec 2022 08:12:59 +0000 Subject: Modify AudioSession to delete old stream when modifySession is called with new remote address. 1) The current code is create a set of audiostream when modifySession called with the new AudioConfig which has new remote address. It make audioSession to keep creates stream everytime the addConfig invoked. I change the code to delete old stream when the modifySession called with AudioConfig with a new remote address. 2) Add UT for the AudioSession Bug: 264833064 Test: atest ImsMediaNativeTests, Verified Voice Call test with forking/non-forking case in live network. Verified by device testing the TC of ATT LTE_BTR_5_5573 pased Change-Id: Icbf809d17113c0afcb24f2ca7c3f093db9bbdc9d --- .../lib/libimsmedia/core/audio/AudioManager.cpp | 3 +- .../lib/libimsmedia/core/audio/AudioSession.cpp | 294 ++++++------------ .../core/audio/AudioStreamGraphRtpRx.cpp | 21 ++ .../core/audio/AudioStreamGraphRtpTx.cpp | 22 ++ .../lib/libimsmedia/core/include/ImsMediaDefine.h | 6 +- .../libimsmedia/core/include/audio/AudioSession.h | 8 + .../core/include/audio/AudioStreamGraph.h | 8 + .../core/include/audio/AudioStreamGraphRtpRx.h | 1 + .../core/include/audio/AudioStreamGraphRtpTx.h | 1 + .../libimsmedia/core/audio/AudioSessionTest.cpp | 337 +++++++++++++++++++++ 10 files changed, 495 insertions(+), 206 deletions(-) create mode 100644 tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/AudioSessionTest.cpp diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/AudioManager.cpp b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/AudioManager.cpp index faabe4fc..357a1d71 100644 --- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/AudioManager.cpp +++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/AudioManager.cpp @@ -97,7 +97,8 @@ ImsMediaResult AudioManager::modifySession(int sessionId, AudioConfig* config) IMLOGI1("[modifySession] sessionId[%d]", sessionId); if (session != mSessions.end()) { - if ((session->second)->IsGraphAlreadyExist(config)) + if ((session->second)->IsGraphAlreadyExist(config) || + (session->second)->getGraphSize(kStreamRtpTx) == 0) { return (session->second)->startGraph(config); } diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/AudioSession.cpp b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/AudioSession.cpp index b2bb681b..e17112f6 100644 --- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/AudioSession.cpp +++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/AudioSession.cpp @@ -18,9 +18,7 @@ #include #include #include - #include - #include AudioSession::AudioSession() @@ -85,7 +83,8 @@ SessionState AudioSession::getState() { if (graph != nullptr && graph->getState() == kStreamStateRunning) { - return kSessionStateActive; + state = kSessionStateSending; + break; } } @@ -93,7 +92,7 @@ SessionState AudioSession::getState() { if (graph != nullptr && graph->getState() == kStreamStateRunning) { - return kSessionStateActive; + return state == kSessionStateSending ? kSessionStateActive : kSessionStateReceiving; } } @@ -101,7 +100,7 @@ SessionState AudioSession::getState() { if (graph != nullptr && graph->getState() == kStreamStateRunning) { - return kSessionStateSuspended; + return state == kSessionStateSending ? kSessionStateSending : kSessionStateSuspended; } } @@ -127,16 +126,15 @@ ImsMediaResult AudioSession::startGraph(RtpConfig* config) ImsMediaResult ret = RESULT_NOT_READY; IMLOGD1("[startGraph] mListGraphRtpTx size[%d]", mListGraphRtpTx.size()); - if (mListGraphRtpTx.size() != 0) - { - for (auto& graph : mListGraphRtpTx) - { - if (graph != nullptr && graph->isSameGraph(config)) + AudioStreamGraphRtpTx* graphTx = AudioStreamGraph::findGraph(mListGraphRtpTx, + [&config](AudioStreamGraphRtpTx* graph) { - ret = graph->update(config); - break; - } - } + return graph != nullptr && graph->isSameGraph(config); + }); + + if (graphTx != nullptr) + { + ret = graphTx->update(config); if (ret != RESULT_SUCCESS) { @@ -147,13 +145,11 @@ ImsMediaResult AudioSession::startGraph(RtpConfig* config) else { mListGraphRtpTx.push_back(new AudioStreamGraphRtpTx(this, mRtpFd)); - ret = mListGraphRtpTx.back()->create(config); - if (ret == RESULT_SUCCESS && - (pConfig->getMediaDirection() == RtpConfig::MEDIA_DIRECTION_SEND_ONLY || - pConfig->getMediaDirection() == RtpConfig::MEDIA_DIRECTION_SEND_RECEIVE)) + if (mListGraphRtpTx.back()->create(config) == RESULT_SUCCESS) { ret = mListGraphRtpTx.back()->start(); + if (ret != RESULT_SUCCESS) { IMLOGE1("[startGraph] start error[%d]", ret); @@ -162,19 +158,18 @@ ImsMediaResult AudioSession::startGraph(RtpConfig* config) } } - IMLOGD1("[startGraph] mListGraphRtpRx size[%d]", mListGraphRtpRx.size()); + IMLOGD1("[startGraph] ListGraphRtpRx size[%d]", mListGraphRtpRx.size()); - if (mListGraphRtpRx.size() != 0) - { - for (auto& graph : mListGraphRtpRx) - { - if (graph != nullptr && graph->isSameGraph(config)) + AudioStreamGraphRtpRx* graphRx = AudioStreamGraph::findGraph(mListGraphRtpRx, + [&config](AudioStreamGraphRtpRx* graph) { - graph->setMediaQualityThreshold(&mThreshold); - ret = graph->update(config); - break; - } - } + return graph != nullptr && graph->isSameGraph(config); + }); + + if (graphRx != nullptr) + { + graphRx->setMediaQualityThreshold(&mThreshold); + ret = graphRx->update(config); if (ret != RESULT_SUCCESS) { @@ -185,11 +180,8 @@ ImsMediaResult AudioSession::startGraph(RtpConfig* config) else { mListGraphRtpRx.push_back(new AudioStreamGraphRtpRx(this, mRtpFd)); - ret = mListGraphRtpRx.back()->create(config); - if (ret == RESULT_SUCCESS && - (pConfig->getMediaDirection() == RtpConfig::MEDIA_DIRECTION_RECEIVE_ONLY || - pConfig->getMediaDirection() == RtpConfig::MEDIA_DIRECTION_SEND_RECEIVE)) + if (mListGraphRtpRx.back()->create(config) == RESULT_SUCCESS) { mListGraphRtpRx.back()->setMediaQualityThreshold(&mThreshold); ret = mListGraphRtpRx.back()->start(); @@ -204,17 +196,16 @@ ImsMediaResult AudioSession::startGraph(RtpConfig* config) IMLOGD1("[startGraph] mListGraphRtcp size[%d]", mListGraphRtcp.size()); - if (mListGraphRtcp.size() != 0) - { - for (auto& graph : mListGraphRtcp) - { - if (graph != nullptr && graph->isSameGraph(config)) + AudioStreamGraphRtcp* graphRtcp = AudioStreamGraph::findGraph(mListGraphRtcp, + [&config](AudioStreamGraphRtcp* graph) { - graph->setMediaQualityThreshold(&mThreshold); - ret = graph->update(config); - break; - } - } + return graph != nullptr && graph->isSameGraph(config); + }); + + if (graphRtcp != nullptr) + { + graphRtcp->setMediaQualityThreshold(&mThreshold); + ret = graphRtcp->update(config); if (ret != RESULT_SUCCESS) { @@ -225,12 +216,12 @@ ImsMediaResult AudioSession::startGraph(RtpConfig* config) else { mListGraphRtcp.push_back(new AudioStreamGraphRtcp(this, mRtcpFd)); - ret = mListGraphRtcp.back()->create(config); - if (ret == RESULT_SUCCESS) + if (mListGraphRtcp.back()->create(config) == RESULT_SUCCESS) { mListGraphRtcp.back()->setMediaQualityThreshold(&mThreshold); ret = mListGraphRtcp.back()->start(); + if (ret != RESULT_SUCCESS) { IMLOGE1("[startGraph] start error[%d]", ret); @@ -262,97 +253,43 @@ ImsMediaResult AudioSession::addGraph(RtpConfig* config, bool enableRtcp) return RESULT_INVALID_PARAM; } - for (auto& graph : mListGraphRtpTx) - { - if (graph != nullptr && graph->isSameGraph(config)) - { - IMLOGW0("[addGraph] same config is exist"); - return startGraph(config); - } - } - - for (auto& graph : mListGraphRtpTx) + if (IsGraphAlreadyExist(config) || mListGraphRtpTx.empty()) { - if (graph != nullptr) - { - graph->stop(); - } + return startGraph(config); } - for (auto& graph : mListGraphRtpRx) + if (enableRtcp) // update current graph to inactive mode { - if (graph != nullptr) + for (auto& graph : mListGraphRtpTx) { - graph->stop(); + if (graph != nullptr) + { + graph->stop(); + } } - } - for (auto& graph : mListGraphRtcp) - { - if (graph != nullptr && graph->getState() != kStreamStateRunning) + for (auto& graph : mListGraphRtpRx) { - enableRtcp ? graph->start() : graph->stop(); + if (graph != nullptr) + { + graph->stop(); + } } - } - - ImsMediaResult ret = RESULT_NOT_READY; - - mListGraphRtpTx.push_back(new AudioStreamGraphRtpTx(this, mRtpFd)); - ret = mListGraphRtpTx.back()->create(config); - if (ret == RESULT_SUCCESS) - { - ret = mListGraphRtpTx.back()->start(); - if (ret != RESULT_SUCCESS) + for (auto& graph : mListGraphRtcp) { - IMLOGE1("[addGraph] start error[%d]", ret); - return ret; + if (graph != nullptr && graph->getState() != kStreamStateRunning) + { + graph->start(); + } } - } - - IMLOGD1("[addGraph] mListGraphTx size[%d]", mListGraphRtpTx.size()); - - mListGraphRtpRx.push_back(new AudioStreamGraphRtpRx(this, mRtpFd)); - ret = mListGraphRtpRx.back()->create(config); - if (ret == RESULT_SUCCESS) - { - mListGraphRtpRx.back()->setMediaQualityThreshold(&mThreshold); - ret = mListGraphRtpRx.back()->start(); - if (ret != RESULT_SUCCESS) - { - IMLOGE1("[addGraph] start error[%d]", ret); - return ret; - } + return startGraph(config); } - - IMLOGD1("[addGraph] mListGraphRx size[%d]", mListGraphRtpRx.size()); - - mListGraphRtcp.push_back(new AudioStreamGraphRtcp(this, mRtcpFd)); - ret = mListGraphRtcp.back()->create(config); - - if (ret == RESULT_SUCCESS) + else { - mListGraphRtcp.back()->setMediaQualityThreshold(&mThreshold); - ret = mListGraphRtcp.back()->start(); - if (ret != RESULT_SUCCESS) - { - IMLOGE1("[addGraph] start error[%d]", ret); - return ret; - } + return confirmGraph(config); } - - IMLOGD1("[addGraph] mListGraphRtcp size[%d]", mListGraphRtcp.size()); - - if (mMediaQualityAnalyzer != nullptr && - !mMediaQualityAnalyzer->isSameConfig(reinterpret_cast(config))) - { - mMediaQualityAnalyzer->stop(); - mMediaQualityAnalyzer->setConfig(reinterpret_cast(config)); - mMediaQualityAnalyzer->start(); - } - - return RESULT_SUCCESS; } ImsMediaResult AudioSession::confirmGraph(RtpConfig* config) @@ -362,99 +299,44 @@ ImsMediaResult AudioSession::confirmGraph(RtpConfig* config) return RESULT_INVALID_PARAM; } - ImsMediaResult ret = RESULT_NOT_READY; - - /** Stop unmatched running instances of StreamGraph. */ - for (auto& graph : mListGraphRtpTx) - { - if (graph != nullptr && !graph->isSameGraph(config)) - { - graph->stop(); - } - } - - for (auto& graph : mListGraphRtpRx) + if (mListGraphRtpTx.empty() || mListGraphRtpRx.empty() || mListGraphRtcp.empty()) { - if (graph != nullptr && !graph->isSameGraph(config)) - { - graph->stop(); - } + return startGraph(config); } - for (auto& graph : mListGraphRtcp) - { - if (graph != nullptr && !graph->isSameGraph(config)) - { - graph->stop(); - } - } - - bool bFound = false; + /** Stop and delete unmatched running instances of StreamGraph. */ for (std::list::iterator iter = mListGraphRtpTx.begin(); iter != mListGraphRtpTx.end();) { AudioStreamGraphRtpTx* graph = *iter; - if (graph == nullptr) - { - continue; - } - - if (!graph->isSameGraph(config)) + if (graph != nullptr && !graph->isSameGraph(config)) { + graph->stop(); iter = mListGraphRtpTx.erase(iter); delete graph; } else { - if (graph->getState() != kStreamStateRunning) - { - ret = graph->start(); - if (ret != RESULT_SUCCESS) - { - IMLOGE1("[confirmGraph] start tx error[%d]", ret); - return ret; - } - } iter++; - bFound = true; } } IMLOGD1("[confirmGraph] mListGraphTx size[%d]", mListGraphRtpTx.size()); - if (bFound == false) - { - IMLOGE0("[confirmGraph] no graph to confirm"); - return RESULT_INVALID_PARAM; - } - for (std::list::iterator iter = mListGraphRtpRx.begin(); iter != mListGraphRtpRx.end();) { AudioStreamGraphRtpRx* graph = *iter; - if (graph == nullptr) - { - continue; - } - - if (!graph->isSameGraph(config)) + if (graph != nullptr && !graph->isSameGraph(config)) { + graph->stop(); iter = mListGraphRtpRx.erase(iter); delete graph; } else { - if (graph->getState() != kStreamStateRunning) - { - ret = graph->start(); - if (ret != RESULT_SUCCESS) - { - IMLOGE1("[confirmGraph] start rx error[%d]", ret); - return ret; - } - } iter++; } } @@ -466,35 +348,21 @@ ImsMediaResult AudioSession::confirmGraph(RtpConfig* config) { AudioStreamGraphRtcp* graph = *iter; - if (graph == nullptr) - { - continue; - } - - if (!graph->isSameGraph(config)) + if (graph != nullptr && !graph->isSameGraph(config)) { + graph->stop(); iter = mListGraphRtcp.erase(iter); delete graph; } else { - if (graph->getState() != kStreamStateRunning) - { - ret = graph->start(); - if (ret != RESULT_SUCCESS) - { - IMLOGE1("[confirmGraph] start rtcp error[%d]", ret); - return ret; - } - } - iter++; } } IMLOGD1("[confirmGraph] mListGraphRtcp size[%d]", mListGraphRtcp.size()); - return RESULT_SUCCESS; + return startGraph(config); } ImsMediaResult AudioSession::deleteGraph(RtpConfig* config) @@ -514,11 +382,7 @@ ImsMediaResult AudioSession::deleteGraph(RtpConfig* config) if (graph->isSameGraph(config)) { - if (graph->getState() == kStreamStateRunning) - { - graph->stop(); - } - + graph->stop(); iter = mListGraphRtpTx.erase(iter); delete graph; bFound = true; @@ -553,6 +417,7 @@ ImsMediaResult AudioSession::deleteGraph(RtpConfig* config) { graph->stop(); } + iter = mListGraphRtpRx.erase(iter); delete graph; break; @@ -581,6 +446,7 @@ ImsMediaResult AudioSession::deleteGraph(RtpConfig* config) { graph->stop(); } + iter = mListGraphRtcp.erase(iter); delete graph; break; @@ -664,6 +530,11 @@ void AudioSession::setMediaQualityThreshold(const MediaQualityThreshold& thresho void AudioSession::sendDtmf(char digit, int duration) { + if (mListGraphRtpTx.empty()) + { + return; + } + for (std::list::iterator iter = mListGraphRtpTx.begin(); iter != mListGraphRtpTx.end(); iter++) { @@ -692,6 +563,21 @@ bool AudioSession::IsGraphAlreadyExist(RtpConfig* config) return false; } +uint32_t AudioSession::getGraphSize(ImsMediaStreamType type) +{ + switch (type) + { + case kStreamRtpTx: + return mListGraphRtpTx.size(); + case kStreamRtpRx: + return mListGraphRtpRx.size(); + case kStreamRtcp: + return mListGraphRtcp.size(); + } + + return 0; +} + void AudioSession::SendInternalEvent(int32_t type, uint64_t param1, uint64_t param2) { (void)param2; diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/AudioStreamGraphRtpRx.cpp b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/AudioStreamGraphRtpRx.cpp index d3d0d791..70963147 100644 --- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/AudioStreamGraphRtpRx.cpp +++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/AudioStreamGraphRtpRx.cpp @@ -106,15 +106,18 @@ ImsMediaResult AudioStreamGraphRtpRx::update(RtpConfig* config) IMLOGI0("[update] pause RX"); return stop(); } + ImsMediaResult ret = RESULT_NOT_READY; if (mGraphState == kStreamStateRunning) { mScheduler->Stop(); + for (auto& node : mListNodeStarted) { IMLOGD1("[update] update node[%s]", node->GetNodeName()); ret = node->UpdateConfig(mConfig); + if (ret != RESULT_SUCCESS) { IMLOGE2("[update] error in update node[%s], ret[%d]", node->GetNodeName(), ret); @@ -128,6 +131,7 @@ ImsMediaResult AudioStreamGraphRtpRx::update(RtpConfig* config) { IMLOGD1("[update] update node[%s]", node->GetNodeName()); ret = node->UpdateConfig(mConfig); + if (ret != RESULT_SUCCESS) { IMLOGE2("[update] error in update node[%s], ret[%d]", node->GetNodeName(), ret); @@ -144,4 +148,21 @@ ImsMediaResult AudioStreamGraphRtpRx::update(RtpConfig* config) } return ret; +} + +ImsMediaResult AudioStreamGraphRtpRx::start() +{ + if (mConfig == nullptr) + { + return RESULT_NOT_READY; + } + + if (mConfig->getMediaDirection() == RtpConfig::MEDIA_DIRECTION_RECEIVE_ONLY || + mConfig->getMediaDirection() == RtpConfig::MEDIA_DIRECTION_SEND_RECEIVE) + { + return BaseStreamGraph::start(); + } + + // not started + return RESULT_SUCCESS; } \ No newline at end of file diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/AudioStreamGraphRtpTx.cpp b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/AudioStreamGraphRtpTx.cpp index 372a137d..1f8260cc 100644 --- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/AudioStreamGraphRtpTx.cpp +++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/AudioStreamGraphRtpTx.cpp @@ -155,6 +155,23 @@ ImsMediaResult AudioStreamGraphRtpTx::update(RtpConfig* config) return ret; } +ImsMediaResult AudioStreamGraphRtpTx::start() +{ + if (mConfig == nullptr) + { + return RESULT_NOT_READY; + } + + if (mConfig->getMediaDirection() == RtpConfig::MEDIA_DIRECTION_SEND_ONLY || + mConfig->getMediaDirection() == RtpConfig::MEDIA_DIRECTION_SEND_RECEIVE) + { + return BaseStreamGraph::start(); + } + + // not started + return RESULT_SUCCESS; +} + bool AudioStreamGraphRtpTx::createDtmfGraph(RtpConfig* config, BaseNode* rtpEncoderNode) { if (config == nullptr) @@ -169,6 +186,11 @@ bool AudioStreamGraphRtpTx::createDtmfGraph(RtpConfig* config, BaseNode* rtpEnco return false; } + if (mConfig == nullptr) + { + mConfig = new AudioConfig(*audioConfig); + } + BaseNode* pDtmfEncoderNode = new DtmfEncoderNode(mCallback); pDtmfEncoderNode->SetMediaType(IMS_MEDIA_AUDIO); pDtmfEncoderNode->SetConfig(audioConfig); diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/ImsMediaDefine.h b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/ImsMediaDefine.h index 74699708..9006f64d 100644 --- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/ImsMediaDefine.h +++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/ImsMediaDefine.h @@ -447,7 +447,11 @@ enum SessionState { /** The state that the session is created but graph is not created */ kSessionStateOpened, - /** The state that the session is created and the Rtp StreamGraphs are running */ + /** The state that the session is created and the TX rtp StreamGraphs are running */ + kSessionStateSending, + /** The state that the session is created and the RX rtp StreamGraphs are running */ + kSessionStateReceiving, + /** The state that the session is created and the both TX and Rx rtp StreamGraphs are running */ kSessionStateActive, /** The state that the session is created and the Rtp StreamGraphs is not running */ kSessionStateSuspended, diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/audio/AudioSession.h b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/audio/AudioSession.h index ce3bd47e..10d8b916 100644 --- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/audio/AudioSession.h +++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/audio/AudioSession.h @@ -95,6 +95,14 @@ public: */ bool IsGraphAlreadyExist(RtpConfig* config); + /** + * @brief Get graph list size with repective stream type + * + * @param type The graph type to fetch + * @return uint32_t The size of list + */ + uint32_t getGraphSize(ImsMediaStreamType type); + private: std::list mListGraphRtpTx; std::list mListGraphRtpRx; diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/audio/AudioStreamGraph.h b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/audio/AudioStreamGraph.h index 203ea682..211b981d 100644 --- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/audio/AudioStreamGraph.h +++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/audio/AudioStreamGraph.h @@ -20,6 +20,7 @@ #include #include #include +#include // std::find_if class AudioStreamGraph : public BaseStreamGraph { @@ -49,6 +50,13 @@ public: mConfig->getRemotePort() == config->getRemotePort()); } + template + static T1* findGraph(std::list list, T2 func) + { + typename std::list::iterator iter = std::find_if(list.begin(), list.end(), func); + return iter == list.end() ? nullptr : *iter; + } + protected: AudioConfig* mConfig; }; diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/audio/AudioStreamGraphRtpRx.h b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/audio/AudioStreamGraphRtpRx.h index cfc9e55f..78e80a82 100644 --- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/audio/AudioStreamGraphRtpRx.h +++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/audio/AudioStreamGraphRtpRx.h @@ -27,6 +27,7 @@ public: virtual ~AudioStreamGraphRtpRx(); virtual ImsMediaResult create(RtpConfig* config); virtual ImsMediaResult update(RtpConfig* config); + virtual ImsMediaResult start(); }; #endif \ No newline at end of file diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/audio/AudioStreamGraphRtpTx.h b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/audio/AudioStreamGraphRtpTx.h index 5853de91..f2cb1744 100644 --- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/audio/AudioStreamGraphRtpTx.h +++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/include/audio/AudioStreamGraphRtpTx.h @@ -27,6 +27,7 @@ public: virtual ~AudioStreamGraphRtpTx(); virtual ImsMediaResult create(RtpConfig* config); virtual ImsMediaResult update(RtpConfig* config); + virtual ImsMediaResult start(); /** * @brief Create a graph for send dtmf digit to network diff --git a/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/AudioSessionTest.cpp b/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/AudioSessionTest.cpp new file mode 100644 index 00000000..bd4a6010 --- /dev/null +++ b/tests/native/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/AudioSessionTest.cpp @@ -0,0 +1,337 @@ +/** + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +using namespace android::telephony::imsmedia; + +// RtpConfig +const int32_t kMediaDirection = RtpConfig::MEDIA_DIRECTION_SEND_RECEIVE; +const android::String8 kRemoteAddress("127.0.0.1"); +const int32_t kRemotePort = 10000; +const int8_t kDscp = 0; +const int8_t kRxPayload = 96; +const int8_t kTxPayload = 96; +const int8_t kSamplingRate = 16; + +// RtcpConfig +const android::String8 kCanonicalName("name"); +const int32_t kTransmitPort = 1001; +const int32_t kIntervalSec = 5; +const int32_t kRtcpXrBlockTypes = RtcpConfig::FLAG_RTCPXR_STATISTICS_SUMMARY_REPORT_BLOCK | + RtcpConfig::FLAG_RTCPXR_VOIP_METRICS_REPORT_BLOCK; + +// AudioConfig +const int8_t kPTimeMillis = 20; +const int32_t kMaxPtimeMillis = 100; +const bool kDtxEnabled = true; +const int32_t kCodecType = AudioConfig::CODEC_AMR_WB; +const int8_t kDtmfTxPayloadTypeNumber = 100; +const int8_t kDtmfRxPayloadTypeNumber = 101; +const int8_t kDtmfsamplingRateKHz = 16; + +// AmrParam +const int32_t kAmrMode = 8; +const bool kOctetAligned = false; +const int32_t kMaxRedundancyMillis = 240; + +// EvsParam +const int32_t kEvsBandwidth = EvsParams::EVS_BAND_NONE; +const int32_t kEvsMode = 8; +const int8_t kChannelAwareMode = 3; +const bool kUseHeaderFullOnly = false; +const int8_t kcodecModeRequest = 15; + +class AudioSessionTest : public ::testing::Test +{ +public: + AudioSession* session; + AudioConfig config; + RtcpConfig rtcp; + AmrParams amr; + EvsParams evs; + int socketRtpFd; + int socketRtcpFd; + + AudioSessionTest() + { + session = nullptr; + socketRtpFd = -1; + socketRtcpFd = -1; + } + ~AudioSessionTest() {} + +protected: + virtual void SetUp() override + { + rtcp.setCanonicalName(kCanonicalName); + rtcp.setTransmitPort(kTransmitPort); + rtcp.setIntervalSec(kIntervalSec); + rtcp.setRtcpXrBlockTypes(kRtcpXrBlockTypes); + + amr.setAmrMode(kAmrMode); + amr.setOctetAligned(kOctetAligned); + amr.setMaxRedundancyMillis(kMaxRedundancyMillis); + + evs.setEvsBandwidth(kEvsBandwidth); + evs.setEvsMode(kEvsMode); + evs.setChannelAwareMode(kChannelAwareMode); + evs.setUseHeaderFullOnly(kUseHeaderFullOnly); + evs.setCodecModeRequest(kcodecModeRequest); + + config.setMediaDirection(kMediaDirection); + config.setRemoteAddress(kRemoteAddress); + config.setRemotePort(kRemotePort); + config.setRtcpConfig(rtcp); + config.setDscp(kDscp); + config.setRxPayloadTypeNumber(kRxPayload); + config.setTxPayloadTypeNumber(kTxPayload); + config.setSamplingRateKHz(kSamplingRate); + config.setPtimeMillis(kPTimeMillis); + config.setMaxPtimeMillis(kMaxPtimeMillis); + config.setDtxEnabled(kDtxEnabled); + config.setCodecType(kCodecType); + config.setTxDtmfPayloadTypeNumber(kDtmfTxPayloadTypeNumber); + config.setRxDtmfPayloadTypeNumber(kDtmfRxPayloadTypeNumber); + config.setDtmfsamplingRateKHz(kDtmfsamplingRateKHz); + config.setAmrParams(amr); + config.setEvsParams(evs); + + session = new AudioSession(); + const char testIp[] = "127.0.0.1"; + unsigned int testPortRtp = 30000; + socketRtpFd = ImsMediaNetworkUtil::openSocket(testIp, testPortRtp, AF_INET); + EXPECT_NE(socketRtpFd, -1); + unsigned int testPortRtcp = 30001; + socketRtcpFd = ImsMediaNetworkUtil::openSocket(testIp, testPortRtcp, AF_INET); + EXPECT_NE(socketRtcpFd, -1); + } + + virtual void TearDown() override + { + if (session != nullptr) + { + delete session; + } + + if (socketRtpFd != -1) + { + ImsMediaNetworkUtil::closeSocket(socketRtpFd); + } + + if (socketRtcpFd != -1) + { + ImsMediaNetworkUtil::closeSocket(socketRtcpFd); + } + } +}; + +TEST_F(AudioSessionTest, testLocalEndpoint) +{ + EXPECT_EQ(session->getState(), kSessionStateOpened); + EXPECT_EQ(session->getLocalRtpFd(), -1); + EXPECT_EQ(session->getLocalRtcpFd(), -1); + + session->setLocalEndPoint(socketRtpFd, socketRtcpFd); + EXPECT_EQ(session->getLocalRtpFd(), socketRtpFd); + EXPECT_EQ(session->getLocalRtcpFd(), socketRtcpFd); +} + +TEST_F(AudioSessionTest, testStartGraphFail) +{ + EXPECT_EQ(session->startGraph(nullptr), RESULT_INVALID_PARAM); + EXPECT_EQ(session->getState(), kSessionStateOpened); + + session->setLocalEndPoint(socketRtpFd, socketRtcpFd); + config.setRemoteAddress(android::String8("")); + EXPECT_EQ(session->startGraph(&config), RESULT_INVALID_PARAM); + EXPECT_EQ(session->getState(), kSessionStateOpened); +} + +TEST_F(AudioSessionTest, testStartGraphAndUpdate) +{ + session->setLocalEndPoint(socketRtpFd, socketRtcpFd); + EXPECT_EQ(session->startGraph(&config), RESULT_SUCCESS); + EXPECT_EQ(session->getState(), kSessionStateActive); + EXPECT_EQ(session->getGraphSize(kStreamRtpTx), 1); + EXPECT_EQ(session->getGraphSize(kStreamRtpRx), 1); + EXPECT_EQ(session->getGraphSize(kStreamRtcp), 1); + + EXPECT_TRUE(session->IsGraphAlreadyExist(&config)); + + // normal update + config.setTxPayloadTypeNumber(120); + EXPECT_EQ(session->startGraph(&config), RESULT_SUCCESS); + EXPECT_EQ(session->getState(), kSessionStateActive); + EXPECT_EQ(session->getGraphSize(kStreamRtpTx), 1); + EXPECT_EQ(session->getGraphSize(kStreamRtpRx), 1); + EXPECT_EQ(session->getGraphSize(kStreamRtcp), 1); + + // create one more graph + config.setRemotePort(20000); + EXPECT_EQ(session->startGraph(&config), RESULT_SUCCESS); + EXPECT_EQ(session->getState(), kSessionStateActive); + EXPECT_EQ(session->getGraphSize(kStreamRtpTx), 2); + EXPECT_EQ(session->getGraphSize(kStreamRtpRx), 2); + EXPECT_EQ(session->getGraphSize(kStreamRtcp), 2); + + config.setRemotePort(30000); + EXPECT_FALSE(session->IsGraphAlreadyExist(&config)); +} + +TEST_F(AudioSessionTest, testStartGraphSendOnly) +{ + session->setLocalEndPoint(socketRtpFd, socketRtcpFd); + config.setMediaDirection(RtpConfig::MEDIA_DIRECTION_SEND_ONLY); + EXPECT_EQ(session->startGraph(&config), RESULT_SUCCESS); + EXPECT_EQ(session->getState(), kSessionStateSending); + EXPECT_EQ(session->getGraphSize(kStreamRtpTx), 1); + EXPECT_EQ(session->getGraphSize(kStreamRtpRx), 1); + EXPECT_EQ(session->getGraphSize(kStreamRtcp), 1); +} + +TEST_F(AudioSessionTest, testStartGraphReceiveOnly) +{ + session->setLocalEndPoint(socketRtpFd, socketRtcpFd); + config.setMediaDirection(RtpConfig::MEDIA_DIRECTION_RECEIVE_ONLY); + EXPECT_EQ(session->startGraph(&config), RESULT_SUCCESS); + EXPECT_EQ(session->getState(), kSessionStateReceiving); + EXPECT_EQ(session->getGraphSize(kStreamRtpTx), 1); + EXPECT_EQ(session->getGraphSize(kStreamRtpRx), 1); + EXPECT_EQ(session->getGraphSize(kStreamRtcp), 1); +} + +TEST_F(AudioSessionTest, testStartGraphInactive) +{ + session->setLocalEndPoint(socketRtpFd, socketRtcpFd); + config.setMediaDirection(RtpConfig::MEDIA_DIRECTION_INACTIVE); + EXPECT_EQ(session->startGraph(&config), RESULT_SUCCESS); + EXPECT_EQ(session->getState(), kSessionStateSuspended); + EXPECT_EQ(session->getGraphSize(kStreamRtpTx), 1); + EXPECT_EQ(session->getGraphSize(kStreamRtpRx), 1); + EXPECT_EQ(session->getGraphSize(kStreamRtcp), 1); +} + +TEST_F(AudioSessionTest, testStartAndHoldResumeWithSameRemoteAddress) +{ + session->setLocalEndPoint(socketRtpFd, socketRtcpFd); + EXPECT_EQ(session->startGraph(&config), RESULT_SUCCESS); + EXPECT_EQ(session->getState(), kSessionStateActive); + + EXPECT_EQ(session->getGraphSize(kStreamRtpTx), 1); + EXPECT_EQ(session->getGraphSize(kStreamRtpRx), 1); + EXPECT_EQ(session->getGraphSize(kStreamRtcp), 1); + + config.setMediaDirection(RtpConfig::MEDIA_DIRECTION_INACTIVE); + EXPECT_EQ(session->startGraph(&config), RESULT_SUCCESS); + EXPECT_EQ(session->getState(), kSessionStateSuspended); + + EXPECT_EQ(session->getGraphSize(kStreamRtpTx), 1); + EXPECT_EQ(session->getGraphSize(kStreamRtpRx), 1); + EXPECT_EQ(session->getGraphSize(kStreamRtcp), 1); +} + +TEST_F(AudioSessionTest, testStartAndHoldResumeWithDifferentRemoteAddress) +{ + session->setLocalEndPoint(socketRtpFd, socketRtcpFd); + EXPECT_EQ(session->startGraph(&config), RESULT_SUCCESS); + EXPECT_EQ(session->getState(), kSessionStateActive); + + config.setRemotePort(20000); + config.setMediaDirection(RtpConfig::MEDIA_DIRECTION_INACTIVE); + EXPECT_EQ(session->addGraph(&config, false), RESULT_SUCCESS); + EXPECT_EQ(session->getState(), kSessionStateSuspended); + + EXPECT_EQ(session->getGraphSize(kStreamRtpTx), 1); + EXPECT_EQ(session->getGraphSize(kStreamRtpRx), 1); + EXPECT_EQ(session->getGraphSize(kStreamRtcp), 1); + + config.setRemotePort(30000); + config.setMediaDirection(RtpConfig::MEDIA_DIRECTION_SEND_RECEIVE); + EXPECT_EQ(session->addGraph(&config, false), RESULT_SUCCESS); + EXPECT_EQ(session->getState(), kSessionStateActive); + + EXPECT_EQ(session->getGraphSize(kStreamRtpTx), 1); + EXPECT_EQ(session->getGraphSize(kStreamRtpRx), 1); + EXPECT_EQ(session->getGraphSize(kStreamRtcp), 1); +} + +TEST_F(AudioSessionTest, testAddGraphWithoutStartGraph) +{ + session->setLocalEndPoint(socketRtpFd, socketRtcpFd); + config.setMediaDirection(RtpConfig::MEDIA_DIRECTION_INACTIVE); + EXPECT_EQ(session->addGraph(&config, false), RESULT_SUCCESS); + EXPECT_EQ(session->getState(), kSessionStateSuspended); + + EXPECT_EQ(session->getGraphSize(kStreamRtpTx), 1); + EXPECT_EQ(session->getGraphSize(kStreamRtpRx), 1); + EXPECT_EQ(session->getGraphSize(kStreamRtcp), 1); + + config.setRemotePort(20000); + config.setMediaDirection(RtpConfig::MEDIA_DIRECTION_SEND_ONLY); + EXPECT_EQ(session->addGraph(&config, false), RESULT_SUCCESS); + EXPECT_EQ(session->getState(), kSessionStateSending); + + EXPECT_EQ(session->getGraphSize(kStreamRtpTx), 1); + EXPECT_EQ(session->getGraphSize(kStreamRtpRx), 1); + EXPECT_EQ(session->getGraphSize(kStreamRtcp), 1); + + config.setRemotePort(30000); + config.setMediaDirection(RtpConfig::MEDIA_DIRECTION_RECEIVE_ONLY); + EXPECT_EQ(session->addGraph(&config, true), RESULT_SUCCESS); + EXPECT_EQ(session->getState(), kSessionStateReceiving); + + EXPECT_EQ(session->getGraphSize(kStreamRtpTx), 2); + EXPECT_EQ(session->getGraphSize(kStreamRtpRx), 2); + EXPECT_EQ(session->getGraphSize(kStreamRtcp), 2); +} + +TEST_F(AudioSessionTest, testStartAddDeleteConfirmGraph) +{ + session->setLocalEndPoint(socketRtpFd, socketRtcpFd); + EXPECT_EQ(session->startGraph(&config), RESULT_SUCCESS); + EXPECT_EQ(session->getState(), kSessionStateActive); + + config.setRemotePort(20000); + EXPECT_EQ(session->addGraph(&config, true), RESULT_SUCCESS); + EXPECT_EQ(session->getState(), kSessionStateActive); + EXPECT_EQ(session->getGraphSize(kStreamRtpTx), 2); + EXPECT_EQ(session->getGraphSize(kStreamRtpRx), 2); + EXPECT_EQ(session->getGraphSize(kStreamRtcp), 2); + + EXPECT_EQ(session->confirmGraph(&config), RESULT_SUCCESS); + EXPECT_EQ(session->getState(), kSessionStateActive); + EXPECT_EQ(session->getGraphSize(kStreamRtpTx), 1); + EXPECT_EQ(session->getGraphSize(kStreamRtpRx), 1); + EXPECT_EQ(session->getGraphSize(kStreamRtcp), 1); +} + +TEST_F(AudioSessionTest, testStartAndAddWithRtcpOff) +{ + session->setLocalEndPoint(socketRtpFd, socketRtcpFd); + EXPECT_EQ(session->startGraph(&config), RESULT_SUCCESS); + EXPECT_EQ(session->getState(), kSessionStateActive); + + config.setRemotePort(20000); + EXPECT_EQ(session->addGraph(&config, false), RESULT_SUCCESS); + EXPECT_EQ(session->getState(), kSessionStateActive); + EXPECT_EQ(session->getGraphSize(kStreamRtpTx), 1); + EXPECT_EQ(session->getGraphSize(kStreamRtpRx), 1); + EXPECT_EQ(session->getGraphSize(kStreamRtcp), 1); +} \ No newline at end of file -- cgit v1.2.3