1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
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
13 * express or implied.
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
17 */
18
19 /*----------------------------------------------------------------------------
20 ; INCLUDES
21 ----------------------------------------------------------------------------*/
22
23 #include "amr_dec.h"
24 #include "frame.h"
25 #include "cnst.h"
26 #include "d_homing.h"
27
28 #define ETS_INPUT_FRAME_SIZE 500
29
30 //Compressed audio formats
31 #define PV_AMR_IETF 0
32 #define PV_AMR_IF2 1
33 #define PV_AMR_ETS 2
34 #define PV_AMR_IETF_COMBINED 3
35
36 //WB modes
37 #define PV_AMRWB_IETF_PAYLOAD 4
38 #define PV_AMRWB_IETF 5
39
40
41 // decoder returns -1 if there is an error in decoding a frame
42 #define PV_GSMAMR_DECODE_STATUS_ERR -1
43
44 // Currently, decoder returns a value >=0 if there is no error.(should be 0)
45 #define PV_GSMAMR_DECODE_STATUS_OK 0
46
47 // Find frame size for each frame type
48 static const OMX_S32 WBIETFFrameSize[16] =
49 {
50 18 // AMR-WB 6.60 Kbps
51 , 24 // AMR-WB 8.85 Kbps
52 , 33 // AMR-WB 12.65 Kbps
53 , 37 // AMR-WB 14.25 Kbps
54 , 41 // AMR-WB 15.85 Kbps
55 , 47 // AMR-WB 18.25 Kbps
56 , 51 // AMR-WB 19.85 Kbps
57 , 59 // AMR-WB 23.05 Kbps
58 , 61 // AMR-WB 23.85 Kbps
59 , 6 // AMR-WB SID
60 , 1
61 , 1
62 , 1
63 , 1
64 , 1 // WBAMR Frame No Data
65 , 1 // WBAMR Frame No Data
66 };
67
68 //////////////////////////////////////////////////////////////////////////////////
69 static const OMX_S32 IETFFrameSize[16] =
70 {
71 13 // AMR 4.75 Kbps
72 , 14 // AMR 5.15 Kbps
73 , 16 // AMR 5.90 Kbps
74 , 18 // AMR 6.70 Kbps
75 , 20 // AMR 7.40 Kbps
76 , 21 // AMR 7.95 Kbps
77 , 27 // AMR 10.2 Kbps
78 , 32 // AMR 12.2 Kbps
79 , 6 // GsmAmr comfort noise
80 , 7 // Gsm-Efr comfort noise
81 , 6 // IS-641 comfort noise
82 , 6 // Pdc-Efr comfort noise
83 , 1 // future use; 0 length but set to 1 to skip the frame type byte
84 , 1 // future use; 0 length but set to 1 to skip the frame type byte
85 , 1 // future use; 0 length but set to 1 to skip the frame type byte
86 , 1 // AMR Frame No Data
87 };
88
89 static const OMX_S32 IF2FrameSize[16] =
90 {
91 13 // AMR 4.75 Kbps
92 , 14 // AMR 5.15 Kbps
93 , 16 // AMR 5.90 Kbps
94 , 18 // AMR 6.70 Kbps
95 , 19 // AMR 7.40 Kbps
96 , 21 // AMR 7.95 Kbps
97 , 26 // AMR 10.2 Kbps
98 , 31 // AMR 12.2 Kbps
99 , 6 // AMR Frame SID
100 , 6 // AMR Frame GSM EFR SID
101 , 6 // AMR Frame TDMA EFR SID
102 , 6 // AMR Frame PDC EFR SID
103 , 1 // future use; 0 length but set to 1 to skip the frame type byte
104 , 1 // future use; 0 length but set to 1 to skip the frame type byte
105 , 1 // future use; 0 length but set to 1 to skip the frame type byte
106 , 1 // AMR Frame No Data
107 };
108
OmxAmrDecoder()109 OmxAmrDecoder::OmxAmrDecoder()
110 {
111 iOmxInputFormat = PV_AMR_ETS;
112 iAMRFramesinTOC = 0;
113 iAmrInitFlag = 0;
114 iNarrowBandFlag = OMX_TRUE;
115
116 //Output frame size in NB would be double the L_FRAME, due to char* output buffer in case of openmax instead of short* in console app
117 iOutputFrameSize = L_FRAME * 2;
118
119 iCodecExternals = NULL;
120 iAudioAmrDecoder = NULL;
121 iTocTablePtr = NULL;
122 /* Initialize decoder homing flags */
123 iDecHomingFlag = 0;
124 iDecHomingFlagOld = 1;
125 }
126
127 /* Decoder Initialization function */
AmrDecInit(OMX_AUDIO_AMRFRAMEFORMATTYPE aInFormat,OMX_AUDIO_AMRBANDMODETYPE aInMode)128 OMX_BOOL OmxAmrDecoder::AmrDecInit(OMX_AUDIO_AMRFRAMEFORMATTYPE aInFormat, OMX_AUDIO_AMRBANDMODETYPE aInMode)
129 {
130 OMX_S32 Status = 0;
131
132 iAmrInitFlag = 0;
133
134 if ((aInMode >= OMX_AUDIO_AMRBandModeNB0) && (aInMode <= OMX_AUDIO_AMRBandModeNB7))
135 {
136 iAudioAmrDecoder = CDecoder_AMR_NB::NewL();
137
138 if (!iAudioAmrDecoder)
139 {
140 return OMX_FALSE;
141 }
142
143 iNarrowBandFlag = OMX_TRUE;
144 iOutputFrameSize = L_FRAME * 2;
145 }
146
147 else if ((aInMode >= OMX_AUDIO_AMRBandModeWB0) && (aInMode <= OMX_AUDIO_AMRBandModeWB8))
148 {
149 iAudioAmrDecoder = CDecoder_AMR_WB::NewL();
150
151 if (!iAudioAmrDecoder)
152 {
153 return OMX_FALSE;
154 }
155
156 iNarrowBandFlag = OMX_FALSE;
157 iOutputFrameSize = L_FRAME * 4;
158 }
159 else
160 {
161 return OMX_FALSE;
162 }
163
164
165 if (!iCodecExternals)
166 {
167 iCodecExternals = OSCL_NEW(tPVAmrDecoderExternal, ());
168 if (!iCodecExternals)
169 {
170 return OMX_FALSE;
171 }
172 }
173
174 //initialize all fields to 0
175 oscl_memset(iCodecExternals, 0, sizeof(tPVAmrDecoderExternal));
176 iCodecExternals->quality = 1; // assume its always good data
177
178 //Extracting the input format information
179 if (OMX_AUDIO_AMRFrameFormatConformance == aInFormat)
180 {
181 iOmxInputFormat = PV_AMR_ETS;
182 iCodecExternals->input_format = ETS;
183 }
184 else if (OMX_AUDIO_AMRFrameFormatIF2 == aInFormat)
185 {
186 iOmxInputFormat = PV_AMR_IF2;
187 iCodecExternals->input_format = IF2;
188 }
189 else if (OMX_AUDIO_AMRFrameFormatRTPPayload == aInFormat)
190 {
191 if (OMX_TRUE == iNarrowBandFlag)
192 {
193 iOmxInputFormat = PV_AMR_IETF_COMBINED;
194 }
195 else
196 {
197 iOmxInputFormat = PV_AMRWB_IETF_PAYLOAD;
198 }
199
200 iCodecExternals->input_format = MIME_IETF;
201 }
202 else if (OMX_AUDIO_AMRFrameFormatFSF == aInFormat)
203 {
204 if (OMX_TRUE == iNarrowBandFlag)
205 {
206 iOmxInputFormat = PV_AMR_IETF;
207 }
208 else
209 {
210 iOmxInputFormat = PV_AMRWB_IETF;
211 }
212
213 iCodecExternals->input_format = MIME_IETF;
214 }
215
216 Status = iAudioAmrDecoder->StartL(iCodecExternals, false, false);
217
218 if (Status)
219 {
220 return OMX_FALSE;
221 }
222
223 return OMX_TRUE;
224 }
225
226
227 /* Decoder De-Initialization function */
AmrDecDeinit()228 void OmxAmrDecoder::AmrDecDeinit()
229 {
230 /* This function call is platform-specific */
231 if (iAudioAmrDecoder)
232 {
233 iAudioAmrDecoder->TerminateDecoderL();
234 OSCL_DELETE(iAudioAmrDecoder);
235 iAudioAmrDecoder = NULL;
236
237 if (iCodecExternals)
238 {
239 OSCL_DELETE(iCodecExternals);
240 iCodecExternals = NULL;
241 }
242 }
243 }
244
245
ResetDecoder()246 void OmxAmrDecoder::ResetDecoder()
247 {
248 if (iAudioAmrDecoder)
249 {
250 iAudioAmrDecoder->ResetDecoderL();
251 }
252 iAMRFramesinTOC = 0;
253 }
254
255
256 /* Find the start point & size of TOC table in case of IETF_Combined format */
GetStartPointsForIETFCombinedMode(OMX_U8 * aPtrIn,OMX_U32 aLength,OMX_U8 * & aTocPtr,OMX_S32 * aNumOfBytes)257 void OmxAmrDecoder::GetStartPointsForIETFCombinedMode
258 (OMX_U8* aPtrIn, OMX_U32 aLength, OMX_U8* &aTocPtr, OMX_S32* aNumOfBytes)
259 {
260 OMX_U8 Fbit = 0x80;
261 OMX_U32 FrameCnt = 0;
262
263 /* Count number of frames */
264 aTocPtr = aPtrIn;
265 while ((*(aTocPtr + FrameCnt) & Fbit) && (FrameCnt < aLength))
266 {
267 FrameCnt++;
268 }
269
270 FrameCnt++;
271 *aNumOfBytes = FrameCnt;
272 }
273
274
275 /* Decode function for all the input formats */
AmrDecodeFrame(OMX_S16 * aOutputBuffer,OMX_U32 * aOutputLength,OMX_U8 ** aInBuffer,OMX_U32 * aInBufSize,OMX_S32 * aIsFirstBuffer)276 OMX_BOOL OmxAmrDecoder::AmrDecodeFrame(OMX_S16* aOutputBuffer,
277 OMX_U32* aOutputLength, OMX_U8** aInBuffer,
278 OMX_U32* aInBufSize, OMX_S32* aIsFirstBuffer)
279 {
280 OMX_BOOL Status = OMX_TRUE;
281 OMX_S32 ByteOffset, ii;
282 TXFrameType TxFrame;
283
284 /* 3GPP Frame Type Buffer */
285 Frame_Type_3GPP FrameType3gpp;
286
287 /* Takes care of extra bytes above the decoded ones
288 * e.g. toc length for ietf_combined, frame header length &
289 * one frame type byte for ietf format.
290 */
291 OMX_S32 FrameBytesProcessed = 0, FrameLength;
292
293 /* Reset speech_bits buffer pointer */
294 OMX_U8* pSpeechBits = *aInBuffer;
295 OMX_U8 *pTocPtr;
296 //ETS mode requires a 16-bit pointer
297 OMX_S16* pEtsSpeechBits = (OMX_S16*) * aInBuffer;
298
299 if ((PV_AMR_IETF_COMBINED == iOmxInputFormat) || (PV_AMR_IETF == iOmxInputFormat)
300 || (PV_AMRWB_IETF_PAYLOAD == iOmxInputFormat) || (PV_AMRWB_IETF == iOmxInputFormat))
301 {
302 if ((PV_AMR_IETF_COMBINED == iOmxInputFormat) || (PV_AMRWB_IETF_PAYLOAD == iOmxInputFormat))
303 {
304 if (0 == iAMRFramesinTOC)
305 {
306 pTocPtr = NULL;
307 GetStartPointsForIETFCombinedMode(pSpeechBits, *aInBufSize,
308 pTocPtr, &iAMRFramesinTOC);
309 pSpeechBits += iAMRFramesinTOC;
310 FrameBytesProcessed = iAMRFramesinTOC;
311
312 iTocTablePtr = pTocPtr;
313 iAMRFramesinTOC--; // ctr of amr frames
314 }
315 else
316 {
317 iAMRFramesinTOC--;
318 FrameBytesProcessed = 0;
319 }
320
321 FrameType3gpp = GetFrameTypeLength(iTocTablePtr, &FrameLength);
322 }
323 else //iOmxInputFormat == PV_AMR_IETF or (PV_AMRWB_IETF == iOmxInputFormat)
324 {
325 if (0 == iAmrInitFlag)
326 {
327 if ('#' == pSpeechBits[0])
328 {
329 pSpeechBits += 6;
330 FrameBytesProcessed = 6;
331 }
332 iAmrInitFlag = 1;
333 }
334
335 FrameType3gpp = GetFrameTypeLength(pSpeechBits, &FrameLength);
336 }
337
338 // check if the frame size exceeds buffer boundaries
339 if ((FrameLength + FrameBytesProcessed) <= (OMX_S32) *aInBufSize)
340 {
341 /* Set up pointer to the start of frame to be decoded */
342 iCodecExternals->mode = (uint32)FrameType3gpp;
343 iCodecExternals->pInputBuffer = (uint8*) pSpeechBits;
344 iCodecExternals->pOutputBuffer = (int16*) aOutputBuffer;
345
346 ByteOffset = iAudioAmrDecoder->ExecuteL(iCodecExternals);
347
348 if (PV_GSMAMR_DECODE_STATUS_ERR == ByteOffset)
349 {
350 *aInBufSize = 0;
351 *aOutputLength = 0;
352 iAMRFramesinTOC = 0; // make sure the TOC table (if necessary) gets initialized for the next time
353 Status = OMX_FALSE;
354 }
355 else
356 {
357 *aInBufSize -= (FrameLength + FrameBytesProcessed);
358 *aInBuffer += (FrameLength + FrameBytesProcessed);
359 *aOutputLength = iOutputFrameSize;
360 // in case of TOC, make sure that
361 // a) if no more data in the buffer and TOC indicates more data, reset TOC
362 // b) if TOC indicates no more data, and there is more data in the buffer, reset the buffer
363 if ((PV_AMR_IETF_COMBINED == iOmxInputFormat) || (PV_AMRWB_IETF_PAYLOAD == iOmxInputFormat))
364 {
365 if ((0 == iAMRFramesinTOC) || (0 == *aInBufSize))
366 {
367 *aInBufSize = 0;
368 iAMRFramesinTOC = 0;
369 }
370 }
371
372 }
373 }
374 else
375 {
376 *aInBufSize = 0;
377 *aOutputLength = 0;
378 iAMRFramesinTOC = 0; // make sure the TOC table (if necessary) gets initialized for the next time
379 Status = OMX_FALSE; // treat buffer overrun as an error
380 }
381
382 }
383 else if (PV_AMR_IF2 == iOmxInputFormat)
384 {
385 FrameType3gpp = (Frame_Type_3GPP)(pSpeechBits[0] & 0xF);
386 FrameLength = IF2FrameSize[FrameType3gpp];
387
388 // check if the frame size exceeds buffer boundaries
389 if ((FrameLength + FrameBytesProcessed) <= (OMX_S32) *aInBufSize)
390 {
391 /* Set up pointer to the start of frame to be decoded */
392 iCodecExternals->mode = (uint32)FrameType3gpp;
393 iCodecExternals->pInputBuffer = (uint8*) pSpeechBits;
394 iCodecExternals->pOutputBuffer = (int16*) aOutputBuffer;
395
396 ByteOffset = iAudioAmrDecoder->ExecuteL(iCodecExternals);
397
398 if (PV_GSMAMR_DECODE_STATUS_ERR == ByteOffset)
399 {
400 Status = OMX_FALSE;
401 }
402
403 if (ByteOffset <= (OMX_S32)*aInBufSize)
404 {
405 *aInBufSize -= ByteOffset;
406 *aInBuffer += ByteOffset;
407 *aOutputLength = iOutputFrameSize;
408 }
409 else
410 {
411 *aInBufSize = 0;
412 *aOutputLength = 0;
413 Status = OMX_FALSE;
414 }
415 }
416 else
417 {
418 *aInBufSize = 0;
419 *aOutputLength = 0;
420 Status = OMX_FALSE; // treat buffer overrun as an error
421 }
422 }
423 else if (PV_AMR_ETS == iOmxInputFormat)
424 {
425 FrameType3gpp = (enum Frame_Type_3GPP) pSpeechBits[(1 + MAX_SERIAL_SIZE) * 2];
426
427 /* Get TX frame type */
428 TxFrame = (TXFrameType)pEtsSpeechBits[0];
429
430 /* Convert TX frame type to RX frame type */
431 switch (TxFrame)
432 {
433 case TX_SPEECH_GOOD:
434 pEtsSpeechBits[0] = RX_SPEECH_GOOD;
435 break;
436
437 case TX_SPEECH_DEGRADED:
438 pEtsSpeechBits[0] = RX_SPEECH_DEGRADED;
439 break;
440
441 case TX_SPEECH_BAD:
442 pEtsSpeechBits[0] = RX_SPEECH_BAD;
443 break;
444
445 case TX_SID_FIRST:
446 pEtsSpeechBits[0] = RX_SID_FIRST;
447 break;
448
449 case TX_SID_UPDATE:
450 pEtsSpeechBits[0] = RX_SID_UPDATE;
451 break;
452
453 case TX_SID_BAD:
454 pEtsSpeechBits[0] = RX_SID_BAD;
455 break;
456
457 case TX_ONSET:
458 pEtsSpeechBits[0] = RX_ONSET;
459 break;
460
461 case TX_NO_DATA:
462 pEtsSpeechBits[0] = RX_NO_DATA;
463 FrameType3gpp = (enum Frame_Type_3GPP) iCodecExternals->mode;
464 break;
465
466 default:
467 break;
468 }
469
470 /* if homed: check if this frame is another homing frame */
471 if (1 == iDecHomingFlagOld)
472 {
473 /* only check until end of first subframe */
474 iDecHomingFlag = decoder_homing_frame_test_first(
475 (OMX_S16*) & pEtsSpeechBits[1],
476 (enum Mode) FrameType3gpp);
477 }
478
479 /* produce encoder homing frame if homed & input=decoder homing frame */
480 if ((0 != iDecHomingFlag) && (0 != iDecHomingFlagOld))
481 {
482 for (ii = 0; ii < L_FRAME; ii++)
483 {
484 aOutputBuffer[ii] = EHF_MASK;
485 }
486 }
487 else
488 {
489 /* Set up pointer to the start of frame to be decoded */
490 iCodecExternals->mode = (uint32)FrameType3gpp;
491 iCodecExternals->pInputBuffer = (uint8*) pEtsSpeechBits;
492 iCodecExternals->pOutputBuffer = (int16*) aOutputBuffer;
493
494 ByteOffset = iAudioAmrDecoder->ExecuteL(iCodecExternals);
495
496 if (PV_GSMAMR_DECODE_STATUS_ERR == ByteOffset)
497 {
498 Status = OMX_FALSE;
499 }
500
501 }
502
503 /* if not homed: check whether current frame is a homing frame */
504 if (0 == iDecHomingFlagOld)
505 {
506 /* check whole frame */
507 iDecHomingFlag = decoder_homing_frame_test(
508 (OMX_S16*) & pEtsSpeechBits[1],
509 (enum Mode) FrameType3gpp);
510 }
511 /* reset decoder if current frame is a homing frame */
512 if (0 != iDecHomingFlag)
513 {
514 iAudioAmrDecoder->ResetDecoderL();
515 }
516
517 iDecHomingFlagOld = iDecHomingFlag;
518
519 //Input buffer requirement per frame is constant at ETS_INPUT_FRAME_SIZE
520 *aInBufSize -= ETS_INPUT_FRAME_SIZE;
521 *aInBuffer += ETS_INPUT_FRAME_SIZE;
522 *aOutputLength = iOutputFrameSize;
523 }
524
525 (*aIsFirstBuffer)++;
526
527 return Status;
528 }
529
530 /* Decode function for all the input formats */
AmrDecodeSilenceFrame(OMX_S16 * aOutputBuffer,OMX_U32 * aOutputLength)531 OMX_BOOL OmxAmrDecoder::AmrDecodeSilenceFrame(OMX_S16* aOutputBuffer,
532 OMX_U32* aOutputLength)
533 {
534 OMX_BOOL Status = OMX_TRUE;
535 OMX_S32 ByteOffset;
536 OMX_U8 FrameType = 15; // silence frame
537
538 iCodecExternals->mode = (uint32) FrameType;
539 iCodecExternals->pInputBuffer = (uint8*) & FrameType;
540 iCodecExternals->pOutputBuffer = (int16*) aOutputBuffer;
541
542 ByteOffset = iAudioAmrDecoder->ExecuteL(iCodecExternals);
543
544 if (PV_GSMAMR_DECODE_STATUS_ERR == ByteOffset)
545 {
546 Status = OMX_FALSE;
547 }
548 else
549 {
550 *aOutputLength = iOutputFrameSize;
551 }
552
553 return Status;
554 }
555
556
557 /* Get Frame type for format == PVMF_AMR_IETF or PVMF_AMR_IETF_COMBINED and the WB counterparts*/
GetFrameTypeLength(OMX_U8 * & aFrame,OMX_S32 * aFrameLength)558 Frame_Type_3GPP OmxAmrDecoder::GetFrameTypeLength(OMX_U8* &aFrame, OMX_S32* aFrameLength)
559 {
560 Frame_Type_3GPP FrameType3gpp;
561
562
563 FrameType3gpp = (Frame_Type_3GPP)((aFrame[0] >> 3) & 0x0F);
564
565 //Narrow Band AMR
566 if (OMX_TRUE == iNarrowBandFlag)
567 {
568 *aFrameLength = IETFFrameSize[FrameType3gpp];
569 }
570 else
571 {
572 *aFrameLength = WBIETFFrameSize[FrameType3gpp];
573 }
574
575
576
577 if (PV_AMR_IETF_COMBINED == iOmxInputFormat || PV_AMRWB_IETF_PAYLOAD == iOmxInputFormat)
578 {
579 // move ptr for TOC
580 aFrame++;
581 (*aFrameLength)--; // account for the 1 byte of length being not in the frame, but in the TOC
582 }
583 else if ((PV_AMR_IETF == iOmxInputFormat) || (PV_AMRWB_IETF == iOmxInputFormat))
584 {
585 aFrame++; // move ptr to data to skip the frame type/size field
586 }
587
588
589 return (FrameType3gpp);
590 }
591