• 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 <IAudioPlayerNode.h>
18 #include <ImsMediaAudioPlayer.h>
19 #include <ImsMediaDefine.h>
20 #include <ImsMediaTrace.h>
21 #include <ImsMediaTimer.h>
22 #include <ImsMediaAudioUtil.h>
23 #include <AudioConfig.h>
24 #include <AudioJitterBuffer.h>
25 #include <string.h>
26 
27 #define MAX_CODEC_EVS_AMR_IO_MODE 9
28 #define JITTER_BUFFER_SIZE_INIT   3
29 #define JITTER_BUFFER_SIZE_MIN    3
30 #define JITTER_BUFFER_SIZE_MAX    11
31 
IAudioPlayerNode(BaseSessionCallback * callback)32 IAudioPlayerNode::IAudioPlayerNode(BaseSessionCallback* callback) :
33         JitterBufferControlNode(callback, IMS_MEDIA_AUDIO)
34 {
35     std::unique_ptr<ImsMediaAudioPlayer> track(new ImsMediaAudioPlayer());
36     mAudioPlayer = std::move(track);
37     mConfig = nullptr;
38     mAnbrDownlinkMode = 0;
39     mIsOctetAligned = false;
40     mIsDtxEnabled = false;
41 }
42 
~IAudioPlayerNode()43 IAudioPlayerNode::~IAudioPlayerNode()
44 {
45     if (mConfig != nullptr)
46     {
47         delete mConfig;
48     }
49 }
50 
GetNodeId()51 kBaseNodeId IAudioPlayerNode::GetNodeId()
52 {
53     return kNodeIdAudioPlayer;
54 }
55 
Start()56 ImsMediaResult IAudioPlayerNode::Start()
57 {
58     IMLOGD2("[Start] codec[%d], mode[%d]", mCodecType, mMode);
59 
60     if (mJitterBuffer)
61     {
62         mJitterBuffer->SetCodecType(mCodecType);
63         reinterpret_cast<AudioJitterBuffer*>(mJitterBuffer)
64                 ->SetEvsRedundantFrameOffset(mEvsChannelAwOffset);
65     }
66 
67     // reset the jitter
68     Reset();
69 
70     if (mAudioPlayer)
71     {
72         mAudioPlayer->SetCodec(mCodecType);
73         mAudioPlayer->SetSamplingRate(mSamplingRate * 1000);
74         mAudioPlayer->SetDtxEnabled(mIsDtxEnabled);
75         mAudioPlayer->SetOctetAligned(mIsOctetAligned);
76         int mode = (mCodecType == kAudioCodecEvs)
77                 ? ImsMediaAudioUtil::GetMaximumEvsMode(mMode)
78                 : ImsMediaAudioUtil::GetMaximumAmrMode(mCodecType, mMode);
79 
80         if (mCodecType == kAudioCodecEvs)
81         {
82             mAudioPlayer->SetEvsBandwidth((int32_t)mEvsBandwidth);
83             mAudioPlayer->SetEvsPayloadHeaderMode(mEvsPayloadHeaderMode);
84             mAudioPlayer->SetEvsChAwOffset(mEvsChannelAwOffset);
85             mRunningCodecMode = ImsMediaAudioUtil::GetMaximumEvsMode(mMode);
86             mAudioPlayer->SetEvsBitRate(
87                     ImsMediaAudioUtil::ConvertEVSModeToBitRate(mRunningCodecMode));
88             mAudioPlayer->SetCodecMode(mRunningCodecMode);
89         }
90         mAudioPlayer->SetCodecMode(mode);
91 
92         mAudioPlayer->Start();
93     }
94     else
95     {
96         IMLOGE0("[IAudioPlayer] Not able to start AudioPlayer");
97     }
98 
99     mNodeState = kNodeStateRunning;
100     StartThread("IAudioPlayerNode");
101     return RESULT_SUCCESS;
102 }
103 
Stop()104 void IAudioPlayerNode::Stop()
105 {
106     IMLOGD0("[Stop]");
107     StopThread();
108     mCondition.reset();
109     mCondition.wait_timeout(AUDIO_STOP_TIMEOUT);
110 
111     if (mAudioPlayer)
112     {
113         mAudioPlayer->Stop();
114     }
115 
116     mNodeState = kNodeStateStopped;
117 }
118 
IsRunTime()119 bool IAudioPlayerNode::IsRunTime()
120 {
121     return true;
122 }
123 
IsSourceNode()124 bool IAudioPlayerNode::IsSourceNode()
125 {
126     return false;
127 }
128 
SetConfig(void * config)129 void IAudioPlayerNode::SetConfig(void* config)
130 {
131     if (config == nullptr)
132     {
133         return;
134     }
135 
136     if (mConfig != nullptr)
137     {
138         delete mConfig;
139         mConfig = nullptr;
140     }
141 
142     mConfig = new AudioConfig(*static_cast<AudioConfig*>(config));
143     mCodecType = ImsMediaAudioUtil::ConvertCodecType(mConfig->getCodecType());
144 
145     if (mCodecType == kAudioCodecAmr || mCodecType == kAudioCodecAmrWb)
146     {
147         mMode = mConfig->getAmrParams().getAmrMode();
148         mIsOctetAligned = mConfig->getAmrParams().getOctetAligned();
149     }
150     else if (mCodecType == kAudioCodecEvs)
151     {
152         mMode = mConfig->getEvsParams().getEvsMode();
153         mEvsChannelAwOffset = mConfig->getEvsParams().getChannelAwareMode();
154         mEvsBandwidth = ImsMediaAudioUtil::FindMaxEvsBandwidthFromRange(
155                 mConfig->getEvsParams().getEvsBandwidth());
156         mEvsPayloadHeaderMode = mConfig->getEvsParams().getUseHeaderFullOnly();
157         mAnbrDownlinkMode = mConfig->getAnbrMode().getAnbrDownlinkCodecMode();
158 
159         if (mAnbrDownlinkMode != 0)
160         {
161             // TODO: need to send cmr bit using HF only mode
162             IMLOGI1("[IAudioPlayerNode] DownlinkMode: %d", mAnbrDownlinkMode);
163         }
164     }
165 
166     mSamplingRate = mConfig->getSamplingRateKHz();
167     mIsDtxEnabled = mConfig->getDtxEnabled();
168 
169     // set the jitter buffer size
170     SetJitterBufferSize(JITTER_BUFFER_SIZE_INIT, JITTER_BUFFER_SIZE_MIN, JITTER_BUFFER_SIZE_MAX);
171 }
172 
IsSameConfig(void * config)173 bool IAudioPlayerNode::IsSameConfig(void* config)
174 {
175     if (config == nullptr)
176     {
177         return true;
178     }
179 
180     AudioConfig* pConfig = reinterpret_cast<AudioConfig*>(config);
181 
182     if (mCodecType == ImsMediaAudioUtil::ConvertCodecType(pConfig->getCodecType()))
183     {
184         if (mCodecType == kAudioCodecAmr || mCodecType == kAudioCodecAmrWb)
185         {
186             return (mMode == pConfig->getAmrParams().getAmrMode() &&
187                     mSamplingRate == pConfig->getSamplingRateKHz() &&
188                     mIsDtxEnabled == pConfig->getDtxEnabled() &&
189                     mIsOctetAligned == pConfig->getAmrParams().getOctetAligned());
190         }
191         else if (mCodecType == kAudioCodecEvs)
192         {
193             return (mMode == pConfig->getEvsParams().getEvsMode() &&
194                     mEvsBandwidth ==
195                             ImsMediaAudioUtil::FindMaxEvsBandwidthFromRange(
196                                     pConfig->getEvsParams().getEvsBandwidth()) &&
197                     mEvsChannelAwOffset == pConfig->getEvsParams().getChannelAwareMode() &&
198                     mSamplingRate == pConfig->getSamplingRateKHz() &&
199                     mEvsPayloadHeaderMode == pConfig->getEvsParams().getUseHeaderFullOnly() &&
200                     mIsDtxEnabled == pConfig->getDtxEnabled());
201         }
202     }
203 
204     return false;
205 }
206 
ProcessCmr(const uint32_t cmrType,const uint32_t cmrDefine)207 void IAudioPlayerNode::ProcessCmr(const uint32_t cmrType, const uint32_t cmrDefine)
208 {
209     IMLOGD2("[ProcessCmr] cmr type[%d], cmrDefine[%d]", cmrType, cmrDefine);
210 
211     if (mAudioPlayer == nullptr)
212     {
213         return;
214     }
215 
216     if (mCodecType == kAudioCodecEvs)
217     {
218         if (cmrType == kEvsCmrCodeTypeNoReq || cmrDefine == kEvsCmrCodeDefineNoReq)
219         {
220             int32_t mode = ImsMediaAudioUtil::GetMaximumEvsMode(mMode);
221 
222             if (mRunningCodecMode != mode)
223             {
224                 mAudioPlayer->ProcessCmr(mode);
225                 mRunningCodecMode = mode;
226             }
227         }
228         else
229         {
230             int32_t mode = MAX_CODEC_EVS_AMR_IO_MODE;
231 
232             IMLOGD1("[ProcessCmr] running codec mode[%d]", mRunningCodecMode);
233 
234             if ((cmrDefine + mode) > mRunningCodecMode)
235             {
236                 IMLOGD1("[ProcessCmr] Skip to change the bitrate for ANBR codec Mode : %d",
237                         (cmrDefine + mode));
238             }
239             else
240             {
241                 switch (cmrType)
242                 {
243                     case kEvsCmrCodeTypeNb:
244                         mEvsBandwidth = kEvsBandwidthNB;
245                         mode += cmrDefine;
246                         break;
247                     case kEvsCmrCodeTypeWb:
248                         mEvsBandwidth = kEvsBandwidthWB;
249                         mode += cmrDefine;
250                         break;
251                     case kEvsCmrCodeTypeSwb:
252                         mEvsBandwidth = kEvsBandwidthSWB;
253                         mode += cmrDefine;
254                         break;
255                     case kEvsCmrCodeTypeFb:
256                         mEvsBandwidth = kEvsBandwidthFB;
257                         mode += cmrDefine;
258                         break;
259                     case kEvsCmrCodeTypeWbCha:
260                         mEvsBandwidth = kEvsBandwidthWB;
261                         mode = kImsAudioEvsPrimaryMode13200;
262                         break;
263                     case kEvsCmrCodeTypeSwbCha:
264                         mEvsBandwidth = kEvsBandwidthSWB;
265                         mode = kImsAudioEvsPrimaryMode13200;
266                         break;
267                     case kEvsCmrCodeTypeAmrIO:
268                         mode = cmrDefine;
269                         break;
270                     default:
271                         break;
272                 }
273 
274                 if (cmrType == kEvsCmrCodeTypeWbCha || cmrType == kEvsCmrCodeTypeSwbCha)
275                 {
276                     switch (cmrDefine)
277                     {
278                         case kEvsCmrCodeDefineChaOffset2:
279                         case kEvsCmrCodeDefineChaOffsetH2:
280                             mEvsChannelAwOffset = 2;
281                             break;
282                         case kEvsCmrCodeDefineChaOffset3:
283                         case kEvsCmrCodeDefineChaOffsetH3:
284                             mEvsChannelAwOffset = 3;
285                             break;
286                         case kEvsCmrCodeDefineChaOffset5:
287                         case kEvsCmrCodeDefineChaOffsetH5:
288                             mEvsChannelAwOffset = 5;
289                             break;
290                         case kEvsCmrCodeDefineChaOffset7:
291                         case kEvsCmrCodeDefineChaOffsetH7:
292                             mEvsChannelAwOffset = 7;
293                             break;
294                         default:
295                             mEvsChannelAwOffset = 3;
296                             break;
297                     }
298                 }
299 
300                 mAudioPlayer->SetEvsBandwidth((int32_t)mEvsBandwidth);
301                 mAudioPlayer->SetEvsChAwOffset(mEvsChannelAwOffset);
302 
303                 if (mode != mRunningCodecMode)
304                 {
305                     mRunningCodecMode = mode;
306                     mAudioPlayer->SetEvsBitRate(
307                             ImsMediaAudioUtil::ConvertEVSModeToBitRate(mRunningCodecMode));
308                     mAudioPlayer->SetCodecMode(mRunningCodecMode);
309                 }
310 
311                 mAudioPlayer->ProcessCmr(mRunningCodecMode);
312             }
313         }
314     }
315 }
316 
AdjustDelay(const int32_t delayMs)317 void IAudioPlayerNode::AdjustDelay(const int32_t delayMs)
318 {
319     if (mJitterBuffer != nullptr)
320     {
321         reinterpret_cast<AudioJitterBuffer*>(mJitterBuffer)->SetAdditionalDelay(delayMs);
322     }
323 }
324 
run()325 void* IAudioPlayerNode::run()
326 {
327     IMLOGD0("[run] enter");
328     SetThreadPriority(getpid(), gettid(), THREAD_PRIORITY_REALTIME);
329     ImsMediaSubType subtype = MEDIASUBTYPE_UNDEFINED;
330     ImsMediaSubType datatype = MEDIASUBTYPE_UNDEFINED;
331     uint8_t* data = nullptr;
332     uint32_t size = 0;
333     uint32_t timestamp = 0;
334     bool mark = false;
335     uint32_t seq = 0;
336     uint32_t lastPlayedSeq = 0;
337     uint32_t currentTime = 0;
338     uint64_t nNextTime = ImsMediaTimer::GetTimeInMicroSeconds();
339     bool isFirstFrameReceived = false;
340 
341 #ifdef FILE_DUMP
342     FILE* file = fopen("/data/user_de/0/com.android.telephony.imsmedia/out.amr", "wb");
343     const uint8_t noDataHeader = 0x7C;
344     const uint8_t amrHeader[] = {0x23, 0x21, 0x41, 0x4d, 0x52, 0x0a};
345     const uint8_t amrWbHeader[] = {0x23, 0x21, 0x41, 0x4d, 0x52, 0x2d, 0x57, 0x42, 0x0a};
346 
347     if (file)
348     {
349         // 1st header of AMR-WB file
350         if (mCodecType == kAudioCodecAmr)
351         {
352             fwrite(amrHeader, sizeof(amrHeader), 1, file);
353         }
354         else if (mCodecType == kAudioCodecAmrWb)
355         {
356             fwrite(amrWbHeader, sizeof(amrWbHeader), 1, file);
357         }
358     }
359 #endif
360     while (true)
361     {
362         if (IsThreadStopped())
363         {
364             IMLOGD0("[run] terminated");
365             break;
366         }
367 
368         if (GetData(&subtype, &data, &size, &timestamp, &mark, &seq, &datatype, &currentTime))
369         {
370             IMLOGD_PACKET3(IM_PACKET_LOG_AUDIO, "[run] write buffer size[%u], TS[%u], datatype[%u]",
371                     size, timestamp, datatype);
372 #ifdef FILE_DUMP
373             size > 0 ? std::fwrite(data, size, 1, file) : std::fwrite(&noDataHeader, 1, 1, file);
374 #endif
375             lastPlayedSeq = seq;
376             FrameType frameType = SPEECH;
377 
378             switch (datatype)
379             {
380                 case MEDIASUBTYPE_AUDIO_SID:
381                     frameType = SID;
382                     break;
383                 case MEDIASUBTYPE_AUDIO_NODATA:
384                     frameType = NO_DATA;
385                     break;
386                 default:
387                 case MEDIASUBTYPE_AUDIO_NORMAL:
388                     frameType = SPEECH;
389                     break;
390             }
391 
392             if (mCallback != nullptr)
393             {
394                 mCallback->SendEvent(kRequestAudioPlayingStatus,
395                         frameType == SPEECH ? kAudioTypeVoice : kAudioTypeNoData, 0);
396             }
397 
398             if (mAudioPlayer->onDataFrame(data, size, frameType, false, 0))
399             {
400                 // send buffering complete message to client
401                 if (!isFirstFrameReceived && mCallback != nullptr)
402                 {
403                     mCallback->SendEvent(kImsMediaEventFirstPacketReceived,
404                             reinterpret_cast<uint64_t>(new AudioConfig(*mConfig)));
405                     isFirstFrameReceived = true;
406                 }
407             }
408 
409             DeleteData();
410         }
411         else if (isFirstFrameReceived)
412         {
413             uint8_t nextFrameByte = 0;
414             bool hasNextFrame = false;
415             uint32_t lostSeq = lastPlayedSeq + 1;
416             if (mRunningCodecMode == kImsAudioEvsPrimaryMode13200 &&
417                     (mEvsChannelAwOffset == 2 || mEvsChannelAwOffset == 3 ||
418                             mEvsChannelAwOffset == 5 || mEvsChannelAwOffset == 7) &&
419                     GetRedundantFrame(lostSeq, &data, &size, &hasNextFrame, &nextFrameByte))
420             {
421                 lastPlayedSeq++;
422                 mAudioPlayer->onDataFrame(data, size, LOST, hasNextFrame, nextFrameByte);
423 
424                 if (mCallback != nullptr)
425                 {
426                     mCallback->SendEvent(kRequestAudioPlayingStatus, kAudioTypeVoice, 0);
427                 }
428             }
429             else
430             {
431                 IMLOGD_PACKET0(IM_PACKET_LOG_AUDIO, "[run] no data");
432                 mAudioPlayer->onDataFrame(nullptr, 0, NO_DATA, false, 0);
433 
434                 if (mCallback != nullptr)
435                 {
436                     mCallback->SendEvent(kRequestAudioPlayingStatus, kAudioTypeNoData, 0);
437                 }
438             }
439 
440 #ifdef FILE_DUMP
441             std::fwrite(&noDataHeader, 1, 1, file);
442 #endif
443         }
444 
445         nNextTime += 20000;
446         uint64_t nCurrTime = ImsMediaTimer::GetTimeInMicroSeconds();
447         int64_t nTime = nNextTime - nCurrTime;
448 
449         if (nTime < 0)
450         {
451             continue;
452         }
453 
454         ImsMediaTimer::USleep(nTime);
455     }
456 #ifdef FILE_DUMP
457     if (file)
458     {
459         fclose(file);
460     }
461 #endif
462     mCondition.signal();
463     return nullptr;
464 }
465