blob: 0f19b6374fd655a30268fcf4ebbcf2a9ccb0673c [file] [log] [blame]
/**
* 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 <AudioStreamGraphRtpRx.h>
#include <IAudioPlayerNode.h>
#include <AudioRtpPayloadDecoderNode.h>
#include <RtpDecoderNode.h>
#include <SocketReaderNode.h>
#include <ImsMediaTrace.h>
#include <ImsMediaNetworkUtil.h>
#include <AudioConfig.h>
AudioStreamGraphRtpRx::AudioStreamGraphRtpRx(BaseSessionCallback* callback, int localFd) :
AudioStreamGraph(callback, localFd)
{
}
AudioStreamGraphRtpRx::~AudioStreamGraphRtpRx() {}
ImsMediaResult AudioStreamGraphRtpRx::create(RtpConfig* config)
{
IMLOGI1("[create] state[%d]", mGraphState);
if (config == nullptr)
{
return RESULT_INVALID_PARAM;
}
mConfig = new AudioConfig(reinterpret_cast<AudioConfig*>(config));
BaseNode* pNodeSocketReader = new SocketReaderNode(mCallback);
pNodeSocketReader->SetMediaType(IMS_MEDIA_AUDIO);
char localIp[MAX_IP_LEN];
uint32_t localPort = 0;
ImsMediaNetworkUtil::getLocalIpPortFromSocket(mLocalFd, localIp, MAX_IP_LEN, localPort);
RtpAddress localAddress(localIp, localPort);
(static_cast<SocketReaderNode*>(pNodeSocketReader))->SetLocalFd(mLocalFd);
(static_cast<SocketReaderNode*>(pNodeSocketReader))->SetLocalAddress(localAddress);
(static_cast<SocketReaderNode*>(pNodeSocketReader))->SetProtocolType(kProtocolRtp);
pNodeSocketReader->SetConfig(config);
pNodeSocketReader->Prepare();
AddNode(pNodeSocketReader);
BaseNode* pNodeRtpDecoder = new RtpDecoderNode(mCallback);
pNodeRtpDecoder->SetMediaType(IMS_MEDIA_AUDIO);
pNodeRtpDecoder->SetConfig(mConfig);
(static_cast<RtpDecoderNode*>(pNodeRtpDecoder))->SetLocalAddress(localAddress);
AddNode(pNodeRtpDecoder);
pNodeSocketReader->ConnectRearNode(pNodeRtpDecoder);
BaseNode* pNodeRtpPayloadDecoder = new AudioRtpPayloadDecoderNode(mCallback);
pNodeRtpPayloadDecoder->SetMediaType(IMS_MEDIA_AUDIO);
pNodeRtpPayloadDecoder->SetConfig(mConfig);
AddNode(pNodeRtpPayloadDecoder);
pNodeRtpDecoder->ConnectRearNode(pNodeRtpPayloadDecoder);
BaseNode* pNodeRenderer = new IAudioPlayerNode(mCallback);
pNodeRenderer->SetMediaType(IMS_MEDIA_AUDIO);
pNodeRenderer->SetConfig(mConfig);
AddNode(pNodeRenderer);
pNodeRtpPayloadDecoder->ConnectRearNode(pNodeRenderer);
setState(StreamState::kStreamStateCreated);
return RESULT_SUCCESS;
}
ImsMediaResult AudioStreamGraphRtpRx::update(RtpConfig* config)
{
IMLOGI1("[update] state[%d]", mGraphState);
if (config == nullptr)
{
return RESULT_INVALID_PARAM;
}
AudioConfig* pConfig = reinterpret_cast<AudioConfig*>(config);
if (*mConfig == *pConfig)
{
IMLOGI0("[update] no update");
return RESULT_SUCCESS;
}
if (mConfig != nullptr)
{
delete mConfig;
}
mConfig = new AudioConfig(pConfig);
if (mConfig->getMediaDirection() == RtpConfig::MEDIA_DIRECTION_NO_FLOW ||
mConfig->getMediaDirection() == RtpConfig::MEDIA_DIRECTION_SEND_ONLY ||
mConfig->getMediaDirection() == RtpConfig::MEDIA_DIRECTION_INACTIVE)
{
IMLOGI0("[update] pause RX");
return stop();
}
ImsMediaResult ret = RESULT_NOT_READY;
bool needsToStart = false;
if (mGraphState == kStreamStateRunning)
{
stop();
needsToStart = true;
}
if (mGraphState == kStreamStateCreated)
{
for (auto& node : mListNodeToStart)
{
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);
}
}
}
if (mGraphState == kStreamStateCreated &&
(pConfig->getMediaDirection() == RtpConfig::MEDIA_DIRECTION_RECEIVE_ONLY ||
pConfig->getMediaDirection() == RtpConfig::MEDIA_DIRECTION_SEND_RECEIVE))
{
IMLOGI0("[update] resume RX");
return start();
}
if (needsToStart)
{
return start();
}
return ret;
}
void AudioStreamGraphRtpRx::processCmr(const uint32_t cmrType, const uint32_t cmrDefine)
{
BaseNode* node = findNode(kNodeIdAudioPlayer);
if (node != nullptr)
{
(reinterpret_cast<IAudioPlayerNode*>(node))->ProcessCmr(cmrType, cmrDefine);
}
}
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;
}