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