• 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 <AudioRtpPayloadDecoderNode.h>
18 #include <ImsMediaAudioUtil.h>
19 #include <ImsMediaTrace.h>
20 #include <AudioConfig.h>
21 
AudioRtpPayloadDecoderNode(BaseSessionCallback * callback)22 AudioRtpPayloadDecoderNode::AudioRtpPayloadDecoderNode(BaseSessionCallback* callback) :
23         BaseNode(callback)
24 {
25     mCodecType = 0;
26     mOctetAligned = 0;
27     memset(mPayload, 0, sizeof(mPayload));
28     mListFrameType.clear();
29     mPrevCMR = 15;
30     mEvsBandwidth = kEvsBandwidthNone;
31     mEvsCodecMode = kEvsCodecModePrimary;
32     mEvsPayloadHeaderMode = kRtpPayloadHeaderModeEvsCompact;
33     mEvsMode = kEvsAmrIoModeBitrate00660;
34     mCoreEvsMode = 0;
35     mEvsOffset = 0;
36     EvsChAOffset = 0;
37 }
38 
~AudioRtpPayloadDecoderNode()39 AudioRtpPayloadDecoderNode::~AudioRtpPayloadDecoderNode() {}
40 
GetNodeId()41 kBaseNodeId AudioRtpPayloadDecoderNode::GetNodeId()
42 {
43     return kNodeIdAudioPayloadDecoder;
44 }
45 
Start()46 ImsMediaResult AudioRtpPayloadDecoderNode::Start()
47 {
48     IMLOGD0("[Start]");
49     mEvsMode = (kEvsBitrate)ImsMediaAudioUtil::GetMaximumEvsMode(mCoreEvsMode);
50     mEvsCodecMode = (kEvsCodecMode)ImsMediaAudioUtil::ConvertEvsCodecMode(mEvsMode);
51 
52     mPrevCMR = mCodecType == kAudioCodecEvs ? 127 : 15;
53     mListFrameType.clear();
54     mNodeState = kNodeStateRunning;
55     return RESULT_SUCCESS;
56 }
57 
Stop()58 void AudioRtpPayloadDecoderNode::Stop()
59 {
60     IMLOGD0("[Stop]");
61     mNodeState = kNodeStateStopped;
62 }
63 
IsRunTime()64 bool AudioRtpPayloadDecoderNode::IsRunTime()
65 {
66     return true;
67 }
68 
IsSourceNode()69 bool AudioRtpPayloadDecoderNode::IsSourceNode()
70 {
71     return false;
72 }
73 
SetConfig(void * config)74 void AudioRtpPayloadDecoderNode::SetConfig(void* config)
75 {
76     AudioConfig* pConfig = reinterpret_cast<AudioConfig*>(config);
77     if (pConfig != nullptr)
78     {
79         mCodecType = ImsMediaAudioUtil::ConvertCodecType(pConfig->getCodecType());
80         if (mCodecType == kAudioCodecAmr || mCodecType == kAudioCodecAmrWb)
81         {
82             mOctetAligned = pConfig->getAmrParams().getOctetAligned();
83         }
84         else if (mCodecType == kAudioCodecEvs)
85         {
86             mEvsBandwidth = pConfig->getEvsParams().getEvsBandwidth();
87             mCoreEvsMode = pConfig->getEvsParams().getEvsMode();
88             mEvsPayloadHeaderMode =
89                     (kRtpPayloadHeaderMode)pConfig->getEvsParams().getUseHeaderFullOnly();
90             mEvsOffset = pConfig->getEvsParams().getChannelAwareMode();
91         }
92     }
93 }
94 
IsSameConfig(void * config)95 bool AudioRtpPayloadDecoderNode::IsSameConfig(void* config)
96 {
97     if (config == nullptr)
98         return true;
99     AudioConfig* pConfig = reinterpret_cast<AudioConfig*>(config);
100 
101     if (mCodecType == ImsMediaAudioUtil::ConvertCodecType(pConfig->getCodecType()))
102     {
103         if (mCodecType == kAudioCodecAmr || mCodecType == kAudioCodecAmrWb)
104         {
105             return (mOctetAligned == pConfig->getAmrParams().getOctetAligned());
106         }
107         else if (mCodecType == kAudioCodecEvs)
108         {
109             return (mEvsBandwidth == pConfig->getEvsParams().getEvsBandwidth() &&
110                     mEvsPayloadHeaderMode ==
111                             (kRtpPayloadHeaderMode)pConfig->getEvsParams().getUseHeaderFullOnly() &&
112                     mCoreEvsMode ==
113                             ImsMediaAudioUtil::GetMaximumEvsMode(
114                                     pConfig->getEvsParams().getEvsMode()) &&
115                     mEvsOffset == pConfig->getEvsParams().getChannelAwareMode());
116         }
117     }
118 
119     return false;
120 }
121 
OnDataFromFrontNode(ImsMediaSubType subtype,uint8_t * pData,uint32_t nDataSize,uint32_t nTimestamp,bool bMark,uint32_t nSeqNum,ImsMediaSubType nDataType,uint32_t arrivalTime)122 void AudioRtpPayloadDecoderNode::OnDataFromFrontNode(ImsMediaSubType subtype, uint8_t* pData,
123         uint32_t nDataSize, uint32_t nTimestamp, bool bMark, uint32_t nSeqNum,
124         ImsMediaSubType nDataType, uint32_t arrivalTime)
125 {
126     if (subtype == MEDIASUBTYPE_REFRESHED)
127     {
128         SendDataToRearNode(
129                 subtype, nullptr, nDataSize, 0, 0, 0, MEDIASUBTYPE_UNDEFINED, arrivalTime);
130         return;
131     }
132 
133     switch (mCodecType)
134     {
135         case kAudioCodecAmr:
136         case kAudioCodecAmrWb:
137             DecodePayloadAmr(pData, nDataSize, nTimestamp, nSeqNum, arrivalTime);
138             break;
139         case kAudioCodecPcmu:
140         case kAudioCodecPcma:
141             SendDataToRearNode(
142                     MEDIASUBTYPE_RTPPAYLOAD, pData, nDataSize, nTimestamp, bMark, nSeqNum);
143             break;
144         case kAudioCodecEvs:
145             DecodePayloadEvs(pData, nDataSize, nTimestamp, bMark, nSeqNum, arrivalTime);
146             break;
147         default:
148             IMLOGE1("[OnDataFromFrontNode] invalid codec type[%d]", mCodecType);
149             SendDataToRearNode(MEDIASUBTYPE_RTPPAYLOAD, pData, nDataSize, nTimestamp, bMark,
150                     nSeqNum, nDataType, arrivalTime);
151             break;
152     }
153 }
154 
DecodePayloadAmr(uint8_t * pData,uint32_t nDataSize,uint32_t nTimestamp,uint32_t nSeqNum,uint32_t arrivalTime)155 void AudioRtpPayloadDecoderNode::DecodePayloadAmr(uint8_t* pData, uint32_t nDataSize,
156         uint32_t nTimestamp, uint32_t nSeqNum, uint32_t arrivalTime)
157 {
158     if (pData == nullptr || nDataSize == 0)
159     {
160         return;
161     }
162 
163     uint32_t timestamp = nTimestamp;
164     uint32_t frameTypeIndex;
165     uint32_t hasNextFrame;
166     uint32_t cmr;
167     uint32_t frameQualityIndicator;  // Q_Speech_Sid_Bad
168 
169     IMLOGD_PACKET5(IM_PACKET_LOG_PH,
170             "[DecodePayloadAmr] codec type[%d], octetAligned[%d], size[%d], TS[%u], "
171             "arrivalTime[%u]",
172             mCodecType, mOctetAligned, nDataSize, timestamp, arrivalTime);
173 
174     mBitReader.SetBuffer(pData, nDataSize);
175     // read cmr
176     cmr = mBitReader.Read(4);
177 
178     if (mOctetAligned)
179     {
180         mBitReader.Read(4);
181     }
182 
183 #ifdef SIMULATE_CMR_AMR
184     const int kMaxMode = mCodecType == kAudioCodecAmrWb ? 9 : 8;
185     static int sCmr = 0;
186     static int sCount = 0;
187     if ((sCount++ % 250) == 0)  // every 5 second
188     {
189         mCallback->SendEvent(kRequestAudioCmr, (sCmr++ % kMaxMode));
190     }
191 #endif
192 
193     if (cmr != mPrevCMR)
194     {
195         if ((mCodecType == kAudioCodecAmr && cmr <= 7) ||
196                 (mCodecType == kAudioCodecAmrWb && cmr <= 8))
197         {
198             IMLOGD2("[DecodePayloadAmr] CMR %d->%d", mPrevCMR, cmr);
199             // send internal event to operate cmr operation in encoder side
200             mCallback->SendEvent(kRequestAudioCmr, cmr);
201             mPrevCMR = cmr;
202         }
203         else if (cmr == 15)
204         {
205             mCallback->SendEvent(kRequestAudioCmr, cmr);
206             mPrevCMR = cmr;
207         }
208         else
209         {
210             IMLOGE1("[DecodePayloadAmr] invalid cmr value %d", cmr);
211         }
212     }
213 
214     // get number of frames
215     do
216     {
217         hasNextFrame = mBitReader.Read(1);           // f(1)
218         frameTypeIndex = mBitReader.Read(4);         // ft(4)
219         frameQualityIndicator = mBitReader.Read(1);  // q(1)
220         IMLOGD_PACKET3(IM_PACKET_LOG_PH, "[DecodePayloadAmr] ToC F=%d, FT=%d, Q=%d", hasNextFrame,
221                 frameTypeIndex, frameQualityIndicator);
222         mListFrameType.push_back(frameTypeIndex);
223         if (mOctetAligned)
224         {
225             mBitReader.Read(2);  // padding
226         }
227     } while (hasNextFrame == 1);
228 
229     // read speech frames
230     while (mListFrameType.size() > 0)
231     {
232         uint32_t dataBitSize;
233         frameTypeIndex = mListFrameType.front();
234         if (mCodecType == kAudioCodecAmr)
235         {
236             dataBitSize = ImsMediaAudioUtil::ConvertAmrModeToBitLen(frameTypeIndex);
237         }
238         else
239         {
240             dataBitSize = ImsMediaAudioUtil::ConvertAmrWbModeToBitLen(frameTypeIndex);
241         }
242 
243         mListFrameType.pop_front();
244         mBitWriter.SetBuffer(mPayload, MAX_AUDIO_PAYLOAD_SIZE);
245         uint32_t bufferSize = (dataBitSize + 7) >> 3;
246 
247         ImsMediaSubType subType =
248                 ImsMediaAudioUtil::GetAmrFrameType(mCodecType, frameTypeIndex, bufferSize);
249 
250         // set TOC
251         mBitWriter.Write(hasNextFrame, 1);
252         mBitWriter.Write(frameTypeIndex, 4);
253         mBitWriter.Write(frameQualityIndicator, 1);
254         mBitWriter.Write(0, 2);
255         mBitReader.ReadByteBuffer(mPayload + 1, dataBitSize);
256         bufferSize++;
257 
258         if (mOctetAligned)
259         {
260             uint32_t paddingSize = (8 - (dataBitSize & 0x07)) & 0x07;
261             mBitReader.Read(paddingSize);
262         }
263 
264         IMLOGD_PACKET6(IM_PACKET_LOG_PH,
265                 "[DecodePayloadAmr] result = %02X %02X %02X %02X, len=%d, FT=%d", mPayload[0],
266                 mPayload[1], mPayload[2], mPayload[3], bufferSize, frameTypeIndex);
267 
268         // send remaining packet number in bundle as bMark value
269         SendDataToRearNode(MEDIASUBTYPE_RTPPAYLOAD, mPayload, bufferSize, timestamp,
270                 mListFrameType.size(), nSeqNum, subType, arrivalTime);
271 
272         timestamp += 20;
273     }
274 }
275 
DecodePayloadEvs(uint8_t * pData,uint32_t nDataSize,uint32_t nTimeStamp,bool bMark,uint32_t nSeqNum,uint32_t arrivalTime)276 void AudioRtpPayloadDecoderNode::DecodePayloadEvs(uint8_t* pData, uint32_t nDataSize,
277         uint32_t nTimeStamp, bool bMark, uint32_t nSeqNum, uint32_t arrivalTime)
278 {
279     if (pData == nullptr || nDataSize == 0)
280     {
281         return;
282     }
283 
284     IMLOGD_PACKET4(IM_PACKET_LOG_PH,
285             "[DecodePayloadEvs] codec type[%d], size[%d], TS[%u], arrivalTime[%u]", mCodecType,
286             nDataSize, nTimeStamp, arrivalTime);
287 
288     kRtpPayloadHeaderMode eEVSReceivedPHFormat = kRtpPayloadHeaderModeEvsCompact;
289     kEvsCodecMode kEvsCodecMode = kEvsCodecModePrimary;
290 
291 #ifdef SIMULATE_CMR_EVS
292     const int kMaxMode = 12;
293     static int sCmr = 1;
294     static int sCount = 0;
295     if ((sCount++ % 250) == 0)  // every 5 second
296     {
297         mCallback->SendEvent(kRequestAudioCmrEvs, kEvsCmrCodeTypeSwb, (sCmr++ % kMaxMode));
298     }
299 #endif
300 
301     // uint32_t nEVSBW = 0;
302     // uint32_t nEVSBR = 0;
303     uint32_t nEVSCompactId = 0;
304     uint32_t nDataBitSize = 0;
305     uint32_t timestamp = nTimeStamp;
306 
307     // CMR byte
308     uint32_t h = 0;      // 1bit, Header Type identification bit(always set to 1)
309     uint32_t cmr_t = 0;  // 3bits, Type of Request
310     uint32_t cmr_d = 0;  // 4bits, Codec Mode Request
311 
312     // ToC byte
313     uint32_t toc_f = 0;     // 1bit, follow another speech frame
314     uint32_t toc_ft_m = 0;  // 1bit, EVS mode
315     uint32_t toc_ft_q = 0;  // 1bit, AMR-WB Q bit
316     uint32_t toc_ft_b = 0;  // 4bits, EVS bit rate
317     ImsMediaSubType subType = MEDIASUBTYPE_AUDIO_NORMAL;
318 
319     mBitReader.SetBuffer(pData, nDataSize);
320 
321     // check RTP payload format
322     eEVSReceivedPHFormat =
323             ImsMediaAudioUtil::ConvertEVSPayloadMode(nDataSize, &kEvsCodecMode, &nEVSCompactId);
324 
325     if (nDataSize == 1)
326     {
327         subType = MEDIASUBTYPE_AUDIO_NODATA;
328         nEVSCompactId = 13;
329     }
330     else if (nDataSize == 5 || nDataSize == 6)
331     {
332         subType = MEDIASUBTYPE_AUDIO_SID;
333     }
334     else if (nDataSize == 7 && (((pData[0] >> 7) == 1 && pData[1] == 12) || pData[0] == 12))
335     {
336         eEVSReceivedPHFormat = kRtpPayloadHeaderModeEvsHeaderFull;
337         subType = MEDIASUBTYPE_AUDIO_SID;
338         nEVSCompactId = 12;
339     }
340     else if (nDataSize == 8 && (pData[0] >> 7) == 1 && pData[1] == 12)
341     {
342         subType = MEDIASUBTYPE_AUDIO_SID;
343         nEVSCompactId = 12;
344     }
345 
346     if ((kEvsCodecMode == kEvsCodecModePrimary) && (nEVSCompactId == 0))  // special case
347     {
348         // first bit of the EVS Primary 2.8kbps in compact format is always set to '0'
349         if ((pData[0] >> 7) == 0)
350         {
351             // EVS Primary 2.8 kbps frame in Compact format
352             eEVSReceivedPHFormat = kRtpPayloadHeaderModeEvsCompact;
353         }
354         else
355         {
356             // EVS AMR-WB IO SID frame in Header-Full format with one CMR byte
357             eEVSReceivedPHFormat = kRtpPayloadHeaderModeEvsHeaderFull;
358         }
359     }
360 
361     if (eEVSReceivedPHFormat == kRtpPayloadHeaderModeEvsCompact)
362     {
363         if (kEvsCodecMode == kEvsCodecModePrimary)
364         {
365             // calculate nDataBitSize from nDataSize
366             uint32_t nFrameType = (uint32_t)ImsMediaAudioUtil::ConvertLenToEVSAudioMode(nDataSize);
367             // TODO: remove kImsAudioEvsMode
368             nDataBitSize =
369                     ImsMediaAudioUtil::ConvertEVSAudioModeToBitLen((kImsAudioEvsMode)nFrameType);
370 
371             mBitReader.ReadByteBuffer(mPayload, nDataBitSize);
372 
373             IMLOGD_PACKET6(IM_PACKET_LOG_PH,
374                     "[DecodePayloadEvs] Result=%02X %02X %02X %02X, len=%d,nFrameType=%d",
375                     mPayload[0], mPayload[1], mPayload[2], mPayload[3], nDataSize, nFrameType);
376 
377             SendDataToRearNode(MEDIASUBTYPE_RTPPAYLOAD, mPayload, nDataSize, timestamp, bMark,
378                     nSeqNum, subType, arrivalTime);
379         }
380         else if (kEvsCodecMode == kEvsCodecModeAmrIo)
381         {
382             // calculate nDataBitSize from nDataSize
383             uint32_t nFrameType = (uint32_t)ImsMediaAudioUtil::ConvertLenToAmrWbMode(nDataSize);
384 
385             nDataBitSize = ImsMediaAudioUtil::ConvertAmrWbModeToBitLen(nFrameType);
386 
387             // read cmr except SID
388             // at EVS AMR WB IO Mode, SID packet does not include cmr field...
389             if (nFrameType != kImsAudioAmrWbModeSID)
390             {
391                 uint32_t cmr = mBitReader.Read(3);
392 
393                 if (cmr != mPrevCMR)
394                 {
395                     if (cmr != kEvsCmrCodeTypeNoReq)
396                     {
397                         ProcessCMRForEVS(kRtpPayloadHeaderModeEvsCompact, kEvsCmrCodeTypeNoReq,
398                                 (kEvsCmrCodeDefine)cmr);
399                         // Save Prev CMR value for checking
400                         mPrevCMR = cmr;
401                     }
402                     else
403                     {
404                         kEvsBandwidth nOriginBW =
405                                 ImsMediaAudioUtil::FindMaxEvsBandwidthFromRange(mEvsBandwidth);
406                         uint32_t nOriginBR = mEvsMode;
407                         kEvsCmrCodeType nCodeType = kEvsCmrCodeTypeNoReq;
408                         kEvsCmrCodeDefine nCodeDefine = kEvsCmrCodeDefineNoReq;
409 
410                         if (mEvsCodecMode == kEvsCodecModePrimary)
411                         {
412                             // to convert EVS CMR type
413                             nOriginBR -= (uint32_t)kEvsPrimaryModeBitrate00590;
414                         }
415 
416                         // check AMR IO and ChA
417                         if (mEvsCodecMode == kEvsCodecModeAmrIo)
418                         {
419                             nCodeType = kEvsCmrCodeTypeAmrIO;
420                             nCodeDefine = (kEvsCmrCodeDefine)nOriginBR;
421                         }
422                         else if ((kEvsPrimaryModeBitrate01320 ==
423                                          (nOriginBR + (uint32_t)kEvsPrimaryModeBitrate00590)) &&
424                                 ((EvsChAOffset > 0) && (EvsChAOffset < 8)))  // ChA case.
425                         {
426                             if (nOriginBW == kEvsBandwidthSWB)
427                             {
428                                 nCodeType = kEvsCmrCodeTypeSwbCha;
429                             }
430                             else
431                             {
432                                 nCodeType = kEvsCmrCodeTypeWbCha;
433                             }
434 
435                             switch (EvsChAOffset)
436                             {
437                                 case 2:
438                                     nCodeDefine = kEvsCmrCodeDefineChaOffsetH2;
439                                     break;
440                                 case 3:
441                                     nCodeDefine = kEvsCmrCodeDefineChaOffsetH3;
442                                     break;
443                                 case 5:
444                                     nCodeDefine = kEvsCmrCodeDefineChaOffsetH5;
445                                     break;
446                                 case 7:
447                                     nCodeDefine = kEvsCmrCodeDefineChaOffsetH7;
448                                     break;
449                                 default:
450                                     IMLOGD3("[DecodePayloadEvs] no selected chmode offset[%d], "
451                                             "originBW[%d], originBR[%d]",
452                                             EvsChAOffset, nOriginBW, nOriginBR);
453                                     nCodeType = kEvsCmrCodeTypeNoReq;
454                                     nCodeDefine = kEvsCmrCodeDefineNoReq;
455                                     break;
456                             }
457                         }
458                         else  // primary case
459                         {
460                             nCodeDefine = (kEvsCmrCodeDefine)nOriginBR;
461 
462                             switch (nOriginBW)
463                             {
464                                 case kEvsBandwidthNB:
465                                     nCodeType = kEvsCmrCodeTypeNb;
466                                     break;
467                                 case kEvsBandwidthWB:
468                                     nCodeType = kEvsCmrCodeTypeWb;
469                                     break;
470                                 case kEvsBandwidthSWB:
471                                     nCodeType = kEvsCmrCodeTypeSwb;
472                                     break;
473                                 case kEvsBandwidthFB:
474                                     nCodeType = kEvsCmrCodeTypeFb;
475                                     break;
476                                 default:
477                                     IMLOGD2("[DecodePayloadEvs] no CodeType - primary mode, "
478                                             "originBW[%d], "
479                                             "originBR[%d]",
480                                             nOriginBW, nOriginBR);
481                                     nCodeType = kEvsCmrCodeTypeNoReq;
482                                     nCodeDefine = kEvsCmrCodeDefineNoReq;
483                                     break;
484                             }
485                         }
486 
487                         // process CMR
488                         ProcessCMRForEVS(
489                                 kRtpPayloadHeaderModeEvsHeaderFull, nCodeType, nCodeDefine);
490 
491                         // Save Prev CMR value for checking
492                         mPrevCMR = cmr;
493                     }
494                 }
495             }
496 
497             mBitReader.ReadByteBuffer(mPayload, nDataBitSize);
498 
499             // last data bit is speech first bit..
500             if (nFrameType != kImsAudioAmrWbModeSID)
501             {
502                 uint8_t nLastBit0 = 0;
503                 uint32_t i = 0;
504                 uint32_t remain = 0;
505 
506                 remain = nDataBitSize % 8;
507                 if (remain == 0)
508                 {
509                     nLastBit0 = mPayload[nDataSize - 1] & 0x01;
510                 }
511                 else
512                 {
513                     nLastBit0 = (mPayload[nDataSize - 1] << (remain - 1)) >> 7;
514                     mPayload[nDataSize - 1] = (mPayload[nDataSize - 1] >> (9 - remain))
515                             << (9 - remain);
516                 }
517 
518                 for (i = (nDataSize - 1); i > 0; i--)
519                 {
520                     mPayload[i] = mPayload[i] >> 1;
521                     mPayload[i] = mPayload[i] + ((mPayload[i - 1] & 0x01) << 7);
522                 }
523                 mPayload[0] = (mPayload[0] >> 1);
524                 mPayload[0] = mPayload[0] + (nLastBit0 << 7);
525             }
526 
527             IMLOGD_PACKET6(IM_PACKET_LOG_PH,
528                     "[DecodePayloadEvs] result = %02X %02X %02X %02X, len=%d, nFrameType=%d",
529                     mPayload[0], mPayload[1], mPayload[2], mPayload[3], nDataSize, nFrameType);
530 
531             SendDataToRearNode(MEDIASUBTYPE_RTPPAYLOAD, mPayload, nDataSize, timestamp, bMark,
532                     nSeqNum, subType, arrivalTime);
533         }
534         else
535         {
536             IMLOGI0("[DecodePayloadEvs] Invalid codec mode");
537             return;
538         }
539     }
540     else if (eEVSReceivedPHFormat == kRtpPayloadHeaderModeEvsHeaderFull)
541     {
542         do
543         {
544             h = mBitReader.Read(1);
545             toc_f = 1;
546 
547             if (h == 1)  // CMR byte
548             {
549                 cmr_t = mBitReader.Read(3);
550                 cmr_d = mBitReader.Read(4);
551                 uint32_t currCmr = (cmr_t << 4) + cmr_d;
552 
553                 if (currCmr != mPrevCMR)
554                 {
555                     // process cmr
556                     if (currCmr != 127)
557                     {
558                         IMLOGI0("[DecodePayloadEvs] Process CMR");
559                         // Process CMR
560                         ProcessCMRForEVS(kRtpPayloadHeaderModeEvsHeaderFull, (kEvsCmrCodeType)cmr_t,
561                                 (kEvsCmrCodeDefine)cmr_d);
562 
563                         // Save Prev CMR value for checking
564                         mPrevCMR = currCmr;
565                     }
566                     else
567                     {
568                         uint32_t nOriginBW =
569                                 ImsMediaAudioUtil::FindMaxEvsBandwidthFromRange(mEvsBandwidth);
570                         uint32_t nOriginBR = mEvsMode;
571                         kEvsCmrCodeType nCodeType = kEvsCmrCodeTypeNoReq;
572                         kEvsCmrCodeDefine nCodeDefine = kEvsCmrCodeDefineNoReq;
573 
574                         if (mEvsCodecMode == kEvsCodecModePrimary)
575                         {
576                             // to convert evs primary mode
577                             nOriginBR -= (uint32_t)kEvsPrimaryModeBitrate00590;
578                         }
579 
580                         // check AMR IO and ChA
581                         if (mEvsCodecMode == kEvsCodecModeAmrIo)
582                         {
583                             nCodeType = kEvsCmrCodeTypeAmrIO;
584                             nCodeDefine = (kEvsCmrCodeDefine)nOriginBR;
585                         }
586                         else if ((kEvsPrimaryModeBitrate01320 ==
587                                          (nOriginBR + (uint32_t)kEvsPrimaryModeBitrate00590)) &&
588                                 ((EvsChAOffset > 0) && (EvsChAOffset < 8)))  // ChA case.
589                         {
590                             if (nOriginBW == (uint32_t)kEvsBandwidthSWB)
591                             {
592                                 nCodeType = kEvsCmrCodeTypeSwbCha;
593                             }
594                             else
595                             {
596                                 nCodeType = kEvsCmrCodeTypeWbCha;
597                             }
598 
599                             switch (EvsChAOffset)
600                             {
601                                 case 2:
602                                     nCodeDefine = kEvsCmrCodeDefineChaOffsetH2;
603                                     break;
604                                 case 3:
605                                     nCodeDefine = kEvsCmrCodeDefineChaOffsetH3;
606                                     break;
607                                 case 5:
608                                     nCodeDefine = kEvsCmrCodeDefineChaOffsetH5;
609                                     break;
610                                 case 7:
611                                     nCodeDefine = kEvsCmrCodeDefineChaOffsetH7;
612                                     break;
613                                 default:
614                                     IMLOGI3("[DecodePayloadEvs] No selected chmode offset[%d], "
615                                             "originBW[%d], originBR[%d]",
616                                             EvsChAOffset, nOriginBW, nOriginBR);
617                                     nCodeType = kEvsCmrCodeTypeNoReq;
618                                     nCodeDefine = kEvsCmrCodeDefineNoReq;
619                                     break;
620                             }
621                         }
622                         else  // primary case
623                         {
624                             nCodeDefine = (kEvsCmrCodeDefine)nOriginBR;
625 
626                             switch (nOriginBW)
627                             {
628                                 case 0:
629                                     nCodeType = kEvsCmrCodeTypeNb;
630                                     break;
631                                 case 1:
632                                     nCodeType = kEvsCmrCodeTypeWb;
633                                     break;
634                                 case 2:
635                                     nCodeType = kEvsCmrCodeTypeSwb;
636                                     break;
637                                 case 3:
638                                     nCodeType = kEvsCmrCodeTypeFb;
639                                     break;
640                                 default:
641                                     IMLOGI2("[DecodePayloadEvs] No CodeType - primary mode, "
642                                             "originBW[%d], "
643                                             "originBR[%d]",
644                                             nOriginBW, nOriginBR);
645                                     nCodeType = kEvsCmrCodeTypeNoReq;
646                                     nCodeDefine = kEvsCmrCodeDefineNoReq;
647                                     break;
648                             }
649                         }
650 
651                         // process CMR
652                         ProcessCMRForEVS(
653                                 kRtpPayloadHeaderModeEvsHeaderFull, nCodeType, nCodeDefine);
654 
655                         // Save Prev CMR value for checking
656                         mPrevCMR = currCmr;
657                     }
658                 }
659             }
660             else  // ToC byte
661             {
662                 toc_f = mBitReader.Read(1);
663                 toc_ft_m = mBitReader.Read(1);
664                 toc_ft_q = mBitReader.Read(1);
665                 toc_ft_b = mBitReader.Read(4);
666 
667                 mListFrameType.push_back(toc_ft_b);
668             }
669         } while (toc_f == 1);
670 
671         //
672         // read speech frames
673         //
674         while (mListFrameType.size() > 0)
675         {
676             mListFrameType.pop_front();
677 
678             if (toc_ft_m == 0)  // EVS Primary mode
679             {
680                 nDataBitSize =
681                         ImsMediaAudioUtil::ConvertEVSAudioModeToBitLen((kImsAudioEvsMode)toc_ft_b);
682             }
683             else  // AMR-WB IO mode
684             {
685                 nDataBitSize = ImsMediaAudioUtil::ConvertAmrWbModeToBitLen(toc_ft_b);
686             }
687 
688             mBitWriter.SetBuffer(mPayload, MAX_AUDIO_PAYLOAD_SIZE);
689             uint32_t bufferSize = (nDataBitSize + 7) >> 3;
690 
691             // set TOC
692             mBitWriter.Write(h, 1);
693             mBitWriter.Write(toc_f, 1);
694             mBitWriter.Write(toc_ft_m, 1);
695             mBitWriter.Write(toc_ft_q, 1);
696             mBitWriter.Write(toc_ft_b, 4);
697             mBitReader.ReadByteBuffer(mPayload + 1, nDataBitSize);
698             bufferSize++;
699 
700             // remove padding bit
701             {
702                 uint32_t nPaddingSize;
703                 nPaddingSize = (8 - (nDataBitSize & 0x07)) & 0x07;
704                 mBitReader.Read(nPaddingSize);
705             }
706 
707             IMLOGD_PACKET6(IM_PACKET_LOG_PH,
708                     "[DecodePayloadEvs] result = %02X %02X %02X %02X, len=%d, eRate=%d",
709                     mPayload[0], mPayload[1], mPayload[2], mPayload[3], bufferSize, toc_ft_b);
710 
711             SendDataToRearNode(MEDIASUBTYPE_RTPPAYLOAD, mPayload, bufferSize, timestamp,
712                     mListFrameType.size(), nSeqNum, subType, arrivalTime);
713 
714             timestamp += 20;
715         }
716     }
717     else
718     {
719         IMLOGE0("[DecodePayloadEvs] Invalid payload format");
720         return;
721     }
722 }
723 
ProcessCMRForEVS(kRtpPayloadHeaderMode eEVSPayloadHeaderMode,kEvsCmrCodeType cmr_t,kEvsCmrCodeDefine cmr_d)724 bool AudioRtpPayloadDecoderNode::ProcessCMRForEVS(
725         kRtpPayloadHeaderMode eEVSPayloadHeaderMode, kEvsCmrCodeType cmr_t, kEvsCmrCodeDefine cmr_d)
726 {
727     kEvsCmrCodeType eNewEVSCMRCodeType = kEvsCmrCodeTypeNoReq;
728     kEvsCmrCodeDefine eNewEVSCMRCodeDefine = kEvsCmrCodeDefineNoReq;
729 
730     if (eEVSPayloadHeaderMode == kRtpPayloadHeaderModeEvsHeaderFull)
731     {
732         if (cmr_t < 8)  // cmr_type is 3bit validation.
733         {
734             eNewEVSCMRCodeType = cmr_t;
735         }
736 
737         if (cmr_d < 16)  // cmr_define is 4bit validation
738         {
739             eNewEVSCMRCodeDefine = cmr_d;
740         }
741     }
742     else if (eEVSPayloadHeaderMode == kRtpPayloadHeaderModeEvsCompact)  // only EVS AMR IO Mode
743     {
744         eNewEVSCMRCodeType = kEvsCmrCodeTypeAmrIO;
745 
746         switch (cmr_d)
747         {
748             case 0:
749                 eNewEVSCMRCodeDefine = kEvsCmrCodeDefineAmrIo660;
750                 break;
751             case 1:
752                 eNewEVSCMRCodeDefine = kEvsCmrCodeDefineAmrIo885;
753                 break;
754             case 2:
755                 eNewEVSCMRCodeDefine = kEvsCmrCodeDefineAmrIo1265;
756                 break;
757             case 3:
758                 eNewEVSCMRCodeDefine = kEvsCmrCodeDefineAmrIo1585;
759                 break;
760             case 4:
761                 eNewEVSCMRCodeDefine = kEvsCmrCodeDefineAmrIo1825;
762                 break;
763             case 5:
764                 eNewEVSCMRCodeDefine = kEvsCmrCodeDefineAmrIo2305;
765                 break;
766             case 6:
767                 eNewEVSCMRCodeDefine = kEvsCmrCodeDefineAmrIo2385;
768                 break;
769             case 7:
770             default:
771                 eNewEVSCMRCodeDefine = kEvsCmrCodeDefineNoReq;
772                 break;
773         }
774     }
775     else
776     {
777         IMLOGI0("[ProcessCMRForEVS] Invalid EVS codec mode");
778         return false;
779     }
780 
781     if (eNewEVSCMRCodeDefine == kEvsCmrCodeDefineNoReq)
782     {
783         IMLOGI0("[ProcessCMRForEVS] Invalid CMR Value");
784         return true;
785     }
786 
787     IMLOGD2("[ProcessCMRForEVS] Change request bnadwidth[%d], bitrate[%d]", eNewEVSCMRCodeType,
788             eNewEVSCMRCodeDefine);
789 
790     if (mCallback)
791     {
792         mCallback->SendEvent(kRequestAudioCmrEvs, eNewEVSCMRCodeType, eNewEVSCMRCodeDefine);
793     }
794 
795     return true;
796 }
797