blob: 0bf0792e226f378c1b9e448db25d8adf2ec9bd7c [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 <IAudioPlayerNode.h>
#include <ImsMediaAudioPlayer.h>
#include <ImsMediaTrace.h>
#include <ImsMediaTimer.h>
#include <ImsMediaAudioUtil.h>
#include <AudioConfig.h>
#include <RtpConfig.h>
#include <string.h>
IAudioPlayerNode::IAudioPlayerNode(BaseSessionCallback* callback) :
JitterBufferControlNode(callback, IMS_MEDIA_AUDIO)
{
std::unique_ptr<ImsMediaAudioPlayer> track(new ImsMediaAudioPlayer());
mAudioPlayer = std::move(track);
}
IAudioPlayerNode::~IAudioPlayerNode() {}
kBaseNodeId IAudioPlayerNode::GetNodeId()
{
return kNodeIdAudioPlayer;
}
ImsMediaResult IAudioPlayerNode::Start()
{
IMLOGD2("[Start] codec[%d], mode[%d]", mCodecType, mMode);
if (mJitterBuffer)
{
mJitterBuffer->SetCodecType(mCodecType);
}
// reset the jitter
Reset();
if (mAudioPlayer)
{
mAudioPlayer->SetCodec(mCodecType);
mAudioPlayer->SetSamplingRate(mSamplingRate * 1000);
if (mCodecType == kAudioCodecEvs)
{
mAudioPlayer->SetEvsBandwidth(mEvsBandwidth);
mAudioPlayer->SetEvsPayloadHeaderMode(mEvsPayloadHeaderMode);
mAudioPlayer->SetEvsBitRate(ImsMediaAudioUtil::ConvertEVSModeToBitRate(
ImsMediaAudioUtil::GetMaximumEvsMode(mMode)));
mAudioPlayer->SetCodecMode(ImsMediaAudioUtil::GetMaximumEvsMode(mMode));
}
mAudioPlayer->Start();
}
else
{
IMLOGE0("[IAudioPlayer] Not able to start AudioPlayer");
}
mFirstFrame = false;
mNodeState = kNodeStateRunning;
StartThread();
return RESULT_SUCCESS;
}
void IAudioPlayerNode::Stop()
{
IMLOGD0("[Stop]");
if (mAudioPlayer)
{
mAudioPlayer->Stop();
}
StopThread();
mCondition.wait_timeout(AUDIO_STOP_TIMEOUT);
mNodeState = kNodeStateStopped;
}
bool IAudioPlayerNode::IsRunTime()
{
return true;
}
bool IAudioPlayerNode::IsSourceNode()
{
return false;
}
void IAudioPlayerNode::SetConfig(void* config)
{
AudioConfig* pConfig = reinterpret_cast<AudioConfig*>(config);
if (pConfig != NULL)
{
mCodecType = ImsMediaAudioUtil::ConvertCodecType(pConfig->getCodecType());
if (mCodecType == kAudioCodecAmr || mCodecType == kAudioCodecAmrWb)
{
mMode = pConfig->getAmrParams().getAmrMode();
}
else if (mCodecType == kAudioCodecEvs)
{
mMode = pConfig->getEvsParams().getEvsMode();
mEvsChannelAwOffset = pConfig->getEvsParams().getChannelAwareMode();
mEvsBandwidth = (kEvsBandwidth)ImsMediaAudioUtil::FindMaxEvsBandwidthFromRange(
pConfig->getEvsParams().getEvsBandwidth());
mEvsPayloadHeaderMode =
(kRtpPyaloadHeaderMode)pConfig->getEvsParams().getUseHeaderFullOnly();
}
mSamplingRate = pConfig->getSamplingRateKHz();
SetJitterBufferSize(4, 4, 9);
SetJitterOptions(80, 1, (double)25 / 10, true, true);
}
}
bool IAudioPlayerNode::IsSameConfig(void* config)
{
if (config == NULL)
{
return true;
}
AudioConfig* pConfig = reinterpret_cast<AudioConfig*>(config);
if (mCodecType == ImsMediaAudioUtil::ConvertCodecType(pConfig->getCodecType()))
{
if (mCodecType == kAudioCodecAmr || mCodecType == kAudioCodecAmrWb)
{
return (mMode == pConfig->getAmrParams().getAmrMode() &&
mSamplingRate == pConfig->getSamplingRateKHz());
}
else if (mCodecType == kAudioCodecEvs)
{
return (mMode == pConfig->getEvsParams().getEvsMode() &&
mEvsBandwidth ==
(kEvsBandwidth)ImsMediaAudioUtil::FindMaxEvsBandwidthFromRange(
pConfig->getEvsParams().getEvsBandwidth()) &&
mEvsChannelAwOffset == pConfig->getEvsParams().getChannelAwareMode() &&
mSamplingRate == pConfig->getSamplingRateKHz() &&
mEvsPayloadHeaderMode == pConfig->getEvsParams().getUseHeaderFullOnly());
}
}
return false;
}
void* IAudioPlayerNode::run()
{
IMLOGD0("[run] enter");
ImsMediaSubType subtype = MEDIASUBTYPE_UNDEFINED;
ImsMediaSubType datatype = MEDIASUBTYPE_UNDEFINED;
uint8_t* pData = NULL;
uint32_t nDataSize = 0;
uint32_t nTimestamp = 0;
bool bMark = false;
uint32_t nSeqNum = 0;
uint64_t nNextTime = ImsMediaTimer::GetTimeInMicroSeconds();
uint64_t nCurrTime = 0;
int64_t nTime = 0;
while (true)
{
if (IsThreadStopped())
{
IMLOGD0("[run] terminated");
mCondition.signal();
break;
}
if (GetData(&subtype, &pData, &nDataSize, &nTimestamp, &bMark, &nSeqNum, &datatype) == true)
{
if (nDataSize != 0)
{
IMLOGD2("[run] write buffer size[%d], TS[%u]", nDataSize, nTimestamp);
if (mAudioPlayer->onDataFrame(pData, nDataSize))
{
// send buffering complete message to client
if (mFirstFrame == false)
{
mCallback->SendEvent(kImsMediaEventFirstPacketReceived);
mFirstFrame = true;
}
}
}
DeleteData();
}
nNextTime += 20000;
nCurrTime = ImsMediaTimer::GetTimeInMicroSeconds();
nTime = nNextTime - nCurrTime;
if (nTime < 0)
{
continue;
}
ImsMediaTimer::USleep(nTime);
}
return NULL;
}