• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <IAudioSourceNode.h>
18 #include <ImsMediaAudioSource.h>
19 #include <ImsMediaTrace.h>
20 #include <ImsMediaAudioUtil.h>
21 #include <ImsMediaTimer.h>
22 #include <string.h>
23 #include <AudioConfig.h>
24 #include <RtpConfig.h>
25 #include <EvsParams.h>
26 #include <AnbrMode.h>
27 
28 #define MAX_CODEC_EVS_AMR_IO_MODE 9
29 
IAudioSourceNode(BaseSessionCallback * callback)30 IAudioSourceNode::IAudioSourceNode(BaseSessionCallback* callback) :
31         BaseNode(callback)
32 {
33     std::unique_ptr<ImsMediaAudioSource> recoder(new ImsMediaAudioSource());
34     mAudioSource = std::move(recoder);
35     mCodecType = 0;
36     mCodecMode = 0;
37     mRunningCodecMode = 0;
38     mFirstFrame = false;
39     mMediaDirection = 0;
40     mAnbrUplinkMode = 0;
41     mIsOctetAligned = false;
42     mIsDtxEnabled = false;
43 }
44 
~IAudioSourceNode()45 IAudioSourceNode::~IAudioSourceNode() {}
46 
GetNodeId()47 kBaseNodeId IAudioSourceNode::GetNodeId()
48 {
49     return kNodeIdAudioSource;
50 }
51 
ProcessStart()52 ImsMediaResult IAudioSourceNode::ProcessStart()
53 {
54     IMLOGD2("[ProcessStart] codec[%d], mode[%d]", mCodecType, mCodecMode);
55 
56     if (mAudioSource)
57     {
58         mAudioSource->SetUplinkCallback(this);
59         mAudioSource->SetCodec(mCodecType);
60         mRunningCodecMode = ImsMediaAudioUtil::GetMaximumAmrMode(mCodecType, mCodecMode);
61         mAudioSource->SetPtime(mPtime);
62         mAudioSource->SetSamplingRate(mSamplingRate * 1000);
63         mAudioSource->SetMediaDirection(mMediaDirection);
64         mAudioSource->SetDtxEnabled(mIsDtxEnabled);
65         mAudioSource->SetOctetAligned(mIsOctetAligned);
66 
67         if (mCodecType == kAudioCodecEvs)
68         {
69             mAudioSource->SetEvsBandwidth((int32_t)mEvsBandwidth);
70             mAudioSource->SetEvsChAwOffset(mEvsChAwOffset);
71             mRunningCodecMode = ImsMediaAudioUtil::GetMaximumEvsMode(mCodecMode);
72             mAudioSource->SetEvsBitRate(
73                     ImsMediaAudioUtil::ConvertEVSModeToBitRate(mRunningCodecMode));
74         }
75         mAudioSource->SetCodecMode(mRunningCodecMode);
76         IMLOGD1("[ProcessStart] running codec mode: %d", mRunningCodecMode);
77 
78         if (mAudioSource->Start())
79         {
80             mNodeState = kNodeStateRunning;
81             mFirstFrame = false;
82             return RESULT_SUCCESS;
83         }
84     }
85     else
86     {
87         IMLOGE0("[IAudioSourceNode] Not able to start AudioSource");
88     }
89 
90     return RESULT_NOT_READY;
91 }
92 
Stop()93 void IAudioSourceNode::Stop()
94 {
95     IMLOGD0("[Stop]");
96 
97     if (mAudioSource)
98     {
99         mAudioSource->Stop();
100     }
101 
102     mNodeState = kNodeStateStopped;
103 }
104 
IsRunTime()105 bool IAudioSourceNode::IsRunTime()
106 {
107     return true;
108 }
109 
IsRunTimeStart()110 bool IAudioSourceNode::IsRunTimeStart()
111 {
112     return false;
113 }
114 
IsSourceNode()115 bool IAudioSourceNode::IsSourceNode()
116 {
117     return true;
118 }
119 
SetConfig(void * config)120 void IAudioSourceNode::SetConfig(void* config)
121 {
122     if (config == nullptr)
123     {
124         return;
125     }
126 
127     AudioConfig* pConfig = reinterpret_cast<AudioConfig*>(config);
128     mCodecType = ImsMediaAudioUtil::ConvertCodecType(pConfig->getCodecType());
129 
130     if (mCodecType == kAudioCodecAmr || mCodecType == kAudioCodecAmrWb)
131     {
132         mCodecMode = pConfig->getAmrParams().getAmrMode();
133         mIsOctetAligned = pConfig->getAmrParams().getOctetAligned();
134     }
135     else if (mCodecType == kAudioCodecEvs)
136     {
137         mCodecMode = pConfig->getEvsParams().getEvsMode();
138         mEvsBandwidth = ImsMediaAudioUtil::FindMaxEvsBandwidthFromRange(
139                 pConfig->getEvsParams().getEvsBandwidth());
140         mEvsChAwOffset = pConfig->getEvsParams().getChannelAwareMode();
141 
142         mAnbrUplinkMode = pConfig->getAnbrMode().getAnbrUplinkCodecMode();
143 
144         if (mAnbrUplinkMode != 0 && mCodecMode != mAnbrUplinkMode)
145         {
146             mCodecMode = mAnbrUplinkMode;
147             IMLOGI2("[SetConfig] new codec mode: %d, uplink mode: %d", mCodecMode, mAnbrUplinkMode);
148         }
149     }
150 
151     mMediaDirection = pConfig->getMediaDirection();
152     mSamplingRate = pConfig->getSamplingRateKHz();
153     mPtime = pConfig->getPtimeMillis();
154     mIsDtxEnabled = pConfig->getDtxEnabled();
155 }
156 
IsSameConfig(void * config)157 bool IAudioSourceNode::IsSameConfig(void* config)
158 {
159     if (config == nullptr)
160     {
161         return true;
162     }
163 
164     AudioConfig* pConfig = reinterpret_cast<AudioConfig*>(config);
165 
166     if (mCodecType == ImsMediaAudioUtil::ConvertCodecType(pConfig->getCodecType()))
167     {
168         if (mCodecType == kAudioCodecAmr || mCodecType == kAudioCodecAmrWb)
169         {
170             return (mCodecMode == pConfig->getAmrParams().getAmrMode() &&
171                     mSamplingRate == pConfig->getSamplingRateKHz() &&
172                     mMediaDirection == pConfig->getMediaDirection() &&
173                     mIsDtxEnabled == pConfig->getDtxEnabled() &&
174                     mIsOctetAligned == pConfig->getAmrParams().getOctetAligned());
175         }
176         else if (mCodecType == kAudioCodecEvs)
177         {
178             return (mCodecMode == pConfig->getEvsParams().getEvsMode() &&
179                     mEvsBandwidth ==
180                             ImsMediaAudioUtil::FindMaxEvsBandwidthFromRange(
181                                     pConfig->getEvsParams().getEvsBandwidth()) &&
182                     mEvsChAwOffset == pConfig->getEvsParams().getChannelAwareMode() &&
183                     mSamplingRate == pConfig->getSamplingRateKHz() &&
184                     mMediaDirection == pConfig->getMediaDirection() &&
185                     mIsDtxEnabled == pConfig->getDtxEnabled());
186         }
187     }
188 
189     return false;
190 }
191 
onDataFrame(uint8_t * buffer,uint32_t size,int64_t timestamp,uint32_t flag)192 void IAudioSourceNode::onDataFrame(uint8_t* buffer, uint32_t size, int64_t timestamp, uint32_t flag)
193 {
194     IMLOGD_PACKET3(IM_PACKET_LOG_AUDIO, "[onDataFrame] size[%zu], TS[%ld], flag[%d]", size,
195             timestamp, flag);
196     SendDataToRearNode(MEDIASUBTYPE_UNDEFINED, buffer, size, ImsMediaTimer::GetTimeInMilliSeconds(),
197             !mFirstFrame, 0, MEDIASUBTYPE_UNDEFINED, ImsMediaTimer::GetTimeInMilliSeconds());
198 
199     if (!mFirstFrame)
200     {
201         mFirstFrame = true;
202     }
203 }
204 
ProcessCmr(const uint32_t cmrType,const uint32_t cmrDefine)205 void IAudioSourceNode::ProcessCmr(const uint32_t cmrType, const uint32_t cmrDefine)
206 {
207     IMLOGD2("[ProcessCmr] cmr type[%d], cmrDefine[%d]", cmrType, cmrDefine);
208 
209     if (mAudioSource == nullptr)
210     {
211         return;
212     }
213 
214     if (mCodecType == kAudioCodecAmr || mCodecType == kAudioCodecAmrWb)
215     {
216         if (cmrType == 15)  // change mode to original one
217         {
218             int32_t mode = ImsMediaAudioUtil::GetMaximumAmrMode(mCodecType, mCodecMode);
219 
220             if (mRunningCodecMode != mode)
221             {
222                 mAudioSource->ProcessCmr(mode);
223                 mRunningCodecMode = mode;
224             }
225         }
226         else
227         {
228             if (mRunningCodecMode != cmrType)
229             {
230                 if (cmrType > mRunningCodecMode && mAnbrUplinkMode == 0)
231                 {
232                     triggerAnbrQuery(cmrType);
233                 }
234                 mAudioSource->ProcessCmr(cmrType);
235                 mRunningCodecMode = cmrType;
236             }
237         }
238     }
239     else if (mCodecType == kAudioCodecEvs)
240     {
241         if (cmrType == kEvsCmrCodeTypeNoReq || cmrDefine == kEvsCmrCodeDefineNoReq)
242         {
243             int32_t mode = ImsMediaAudioUtil::GetMaximumEvsMode(mCodecMode);
244 
245             if (mRunningCodecMode != mode)
246             {
247                 mAudioSource->ProcessCmr(mode);
248                 mRunningCodecMode = mode;
249             }
250         }
251         else
252         {
253             // triggering ANBR query- build triggerAnbrQuery (with mode: cmr)
254             int32_t mode = MAX_CODEC_EVS_AMR_IO_MODE;
255 
256             if ((cmrDefine + mode) > mRunningCodecMode && mAnbrUplinkMode == 0)
257             {
258                 triggerAnbrQuery(mode + cmrDefine);
259             }
260 
261             switch (cmrType)
262             {
263                 case kEvsCmrCodeTypeNb:
264                     mEvsBandwidth = kEvsBandwidthNB;
265                     mode += cmrDefine;
266                     break;
267                 case kEvsCmrCodeTypeWb:
268                     mEvsBandwidth = kEvsBandwidthWB;
269                     mode += cmrDefine;
270                     break;
271                 case kEvsCmrCodeTypeSwb:
272                     mEvsBandwidth = kEvsBandwidthSWB;
273                     mode += cmrDefine;
274                     break;
275                 case kEvsCmrCodeTypeFb:
276                     mEvsBandwidth = kEvsBandwidthFB;
277                     mode += cmrDefine;
278                     break;
279                 case kEvsCmrCodeTypeWbCha:
280                     mEvsBandwidth = kEvsBandwidthWB;
281                     mode = kImsAudioEvsPrimaryMode13200;
282                     break;
283                 case kEvsCmrCodeTypeSwbCha:
284                     mEvsBandwidth = kEvsBandwidthSWB;
285                     mode = kImsAudioEvsPrimaryMode13200;
286                     break;
287                 case kEvsCmrCodeTypeAmrIO:
288                     mode = cmrDefine;
289                     break;
290                 default:
291                     break;
292             }
293 
294             if (cmrType == kEvsCmrCodeTypeWbCha || cmrType == kEvsCmrCodeTypeSwbCha)
295             {
296                 switch (cmrDefine)
297                 {
298                     case kEvsCmrCodeDefineChaOffset2:
299                     case kEvsCmrCodeDefineChaOffsetH2:
300                         mEvsChAwOffset = 2;
301                         break;
302                     case kEvsCmrCodeDefineChaOffset3:
303                     case kEvsCmrCodeDefineChaOffsetH3:
304                         mEvsChAwOffset = 3;
305                         break;
306                     case kEvsCmrCodeDefineChaOffset5:
307                     case kEvsCmrCodeDefineChaOffsetH5:
308                         mEvsChAwOffset = 5;
309                         break;
310                     case kEvsCmrCodeDefineChaOffset7:
311                     case kEvsCmrCodeDefineChaOffsetH7:
312                         mEvsChAwOffset = 7;
313                         break;
314                     default:
315                         mEvsChAwOffset = 3;
316                         break;
317                 }
318             }
319 
320             mAudioSource->SetEvsBandwidth((int32_t)mEvsBandwidth);
321             mAudioSource->SetEvsChAwOffset(mEvsChAwOffset);
322 
323             if (mode != mRunningCodecMode)
324             {
325                 mRunningCodecMode = mode;
326                 mAudioSource->SetEvsBitRate(
327                         ImsMediaAudioUtil::ConvertEVSModeToBitRate(mRunningCodecMode));
328                 mAudioSource->SetCodecMode(mRunningCodecMode);
329             }
330 
331             mAudioSource->ProcessCmr(mRunningCodecMode);
332         }
333     }
334 }
335 
triggerAnbrQuery(uint32_t cmr)336 void IAudioSourceNode::triggerAnbrQuery(uint32_t cmr)
337 {
338     AnbrMode param;
339 
340     IMLOGD1("[triggerAnbrQuery] - mode : %d", cmr);
341 
342     param.setAnbrUplinkCodecMode(cmr);
343     param.setAnbrDownlinkCodecMode(0);
344 
345     AudioConfig* audioConfig = new AudioConfig();
346     audioConfig->setAnbrMode(param);
347 
348     mCallback->SendEvent(kAudioTriggerAnbrQueryInd, reinterpret_cast<uint64_t>(audioConfig));
349 }
350