diff options
author | Andreas Huber <andih@google.com> | 2009-12-07 09:56:32 -0800 |
---|---|---|
committer | Andreas Huber <andih@google.com> | 2009-12-07 11:02:28 -0800 |
commit | dacaa73ae5010b66f4224d70a520945e5b653544 (patch) | |
tree | a2c9e71b6337dd25d149bd5fa43f7a782e9387fb /media/libstagefright/codecs/aacdec/q_normalize.cpp | |
parent | 5921fb51e0219ddd7cad439a73495f320c57d50e (diff) | |
download | frameworks_base-dacaa73ae5010b66f4224d70a520945e5b653544.zip frameworks_base-dacaa73ae5010b66f4224d70a520945e5b653544.tar.gz frameworks_base-dacaa73ae5010b66f4224d70a520945e5b653544.tar.bz2 |
Initial check in of stagefright software AAC decoder based on PV source code.
Diffstat (limited to 'media/libstagefright/codecs/aacdec/q_normalize.cpp')
-rw-r--r-- | media/libstagefright/codecs/aacdec/q_normalize.cpp | 388 |
1 files changed, 388 insertions, 0 deletions
diff --git a/media/libstagefright/codecs/aacdec/q_normalize.cpp b/media/libstagefright/codecs/aacdec/q_normalize.cpp new file mode 100644 index 0000000..5266966 --- /dev/null +++ b/media/libstagefright/codecs/aacdec/q_normalize.cpp @@ -0,0 +1,388 @@ +/* ------------------------------------------------------------------ + * Copyright (C) 1998-2009 PacketVideo + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + * ------------------------------------------------------------------- + */ +/* + + Pathname: q_normalize.c + +------------------------------------------------------------------------------ + REVISION HISTORY + + Description: + (1) Modify to include search over the scalefactor bands to insure + that the data is using all 31 data-bits. + + Description: + (1) Modify to remove search over the scalefactor bands to insure + that the data is using all 31 data-bits. + (Pushed out into separate function) + (2) Change variable "k" to more descriptive "shift_amt" + (3) Update pseudocode to reflect removed code. + (4) Add PV Copyright notice. + + Description: + (1) Modified to protect q-normalize from shifting by amounts >= 32. + + Description: + (1) Delete local variable idx_count. + + Description: + (1) Included search for max in each frame, modified interface. + + Description: + (1) unrolled loop based on the fact that the size of each scale band + is always an even number. + + Description:Check shift, if zero, do not shift. + + Description: Eliminated warning: non use variable "i" and memset function + definition + + Who: Date: + Description: +------------------------------------------------------------------------------ + INPUT AND OUTPUT DEFINITIONS + + Inputs: + qFormat[] = Array of qFormats, one per scalefactor band. [ Int ] + + pFrameInfo = Pointer to structure that holds information about each group. + (long block flag, number of windows, scalefactor bands, etc.) + [const FrameInfo] + + coef[] = Array of the spectral coefficients for one channel. [ Int32 ] + + Local Stores/Buffers/Pointers Needed: + None + + Global Stores/Buffers/Pointers Needed: + None + + Outputs: + min_q = The common q-format for the entire frame. [Int] + + Pointers and Buffers Modified: + coef[] = Array of spectral data, now normalized to one q-format. + + Local Stores Modified: + None + + Global Stores Modified: + None + +------------------------------------------------------------------------------ + FUNCTION DESCRIPTION + + This module first scans every scalefactor band for the frame, insuring that + at least one element in that scalefactor band is using all available bits. + If not, the elements in the scalefactor band are shifted up to use all 31 + data bits. The q-format is adjusted accordingly. + + This module then scans the q-formats for each scalefactor band. + Upon finding the minimum q-format in the frame, the coefficients in each + scalefactor band are normalized to the minimum q-format. + The minimum q-format is then returned to the calling function, which is now + the q-format for the entire frame. + +------------------------------------------------------------------------------ + REQUIREMENTS + +------------------------------------------------------------------------------ + REFERENCES + +------------------------------------------------------------------------------ + PSEUDO-CODE + + nwin = pFrameInfo->num_win; + + pQformat = &(qFormat[0]); + pSfbPerWin = &(pFrameInfo->sfb_per_win[0]); + pCoef = &(coef[0]); + + FOR (win = nwin; win > 0; win--) + + nsfb = *(pSfbPerWin++); + + FOR (sfb = nsfb; sfb > 0; sfb--) + + IF ( *(pQformat) < min_q) + min_q = *(pQformat); + ENDIF + + pQformat++; + + ENDFOR + + ENDFOR + + pQformat = &(qFormat[0]); + pSfbPerWin = &(pFrameInfo->sfb_per_win[0]); + pCoef = &(coef[0]); + + FOR (win = 0; win < nwin; win++) + + stop_idx = 0; + + nsfb = *(pSfbPerWin++); + + pWinSfbTop = &(pFrameInfo->win_sfb_top[win][0]); + + FOR (sfb = nsfb; sfb > 0; sfb--) + + sfbWidth = *(pWinSfbTop++) - stop_idx; + + stop_idx += sfbWidth; + + k = *(pQformat++) - min_q; + + IF (k < 32) + THEN + FOR (; sfbWidth > 0; sfbWidth--) + *(pCoef++) >>= k; + ENDFOR + ELSE + FOR (; sfbWidth > 0; sfbWidth--) + *(pCoef++) = 0; + ENDFOR + ENDIF + + ENDFOR + + ENDFOR + + return min_q; + +------------------------------------------------------------------------------ + RESOURCES USED + When the code is written for a specific target processor the + the resources used should be documented below. + + STACK USAGE: [stack count for this module] + [variable to represent + stack usage for each subroutine called] + + where: [stack usage variable] = stack usage for [subroutine + name] (see [filename].ext) + + DATA MEMORY USED: x words + + PROGRAM MEMORY USED: x words + + CLOCK CYCLES: [cycle count equation for this module] + [variable + used to represent cycle count for each subroutine + called] + + where: [cycle count variable] = cycle count for [subroutine + name] (see [filename].ext) + +------------------------------------------------------------------------------ +*/ + + +/*---------------------------------------------------------------------------- +; INCLUDES +----------------------------------------------------------------------------*/ +#include "pv_audio_type_defs.h" +#include "s_frameinfo.h" +#include "q_normalize.h" +#include "aac_mem_funcs.h" /* For pv_memset */ + +/*---------------------------------------------------------------------------- +; MACROS +; Define module specific macros here +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; DEFINES +; Include all pre-processor statements here. Include conditional +; compile variables also. +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL FUNCTION DEFINITIONS +; Function Prototype declaration +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; LOCAL STORE/BUFFER/POINTER DEFINITIONS +; Variable declaration - defined here and used outside this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL FUNCTION REFERENCES +; Declare functions defined elsewhere and referenced in this module +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES +; Declare variables used in this module but defined elsewhere +----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +; FUNCTION CODE +----------------------------------------------------------------------------*/ +Int q_normalize( + Int qFormat[], + const FrameInfo *pFrameInfo, + Int32 abs_max_per_window[], + Int32 coef[]) +{ + Int sfb; + Int nsfb; + Int win; + Int nwin; + Int sfbWidth; + + Int shift_amt; + + /* Initialize min_q to a very large value */ + Int min_q = 1000; + + Int stop_idx = 0; + + const Int *pSfbPerWin; + const Int16 *pWinSfbTop; + + Int *pQformat; + Int32 *pCoef; + + nwin = pFrameInfo->num_win; + + /* Find the minimum q format */ + pQformat = &(qFormat[0]); + pSfbPerWin = &(pFrameInfo->sfb_per_win[0]); + + for (win = nwin; win != 0; win--) + { + + nsfb = *(pSfbPerWin++); + + if (nsfb < 0 || nsfb > MAXBANDS) + { + break; /* avoid any processing on error condition */ + } + + for (sfb = nsfb; sfb != 0; sfb--) + { + Int qformat = *(pQformat++); + if (qformat < min_q) + { + min_q = qformat; + } + } + + } /* for(win) */ + + /* Normalize the coefs in each scalefactor band to one q-format */ + pQformat = &(qFormat[0]); + pSfbPerWin = &(pFrameInfo->sfb_per_win[0]); + pCoef = &(coef[0]); + + for (win = 0; win < nwin; win++) + { + + Int32 max = 0; + stop_idx = 0; + + nsfb = *(pSfbPerWin++); + + if (nsfb < 0 || nsfb > MAXBANDS) + { + break; /* avoid any processing on error condition */ + } + + pWinSfbTop = &(pFrameInfo->win_sfb_top[win][0]); + + for (sfb = nsfb; sfb != 0; sfb--) + { + Int tmp1, tmp2; + tmp1 = *(pWinSfbTop++); + tmp2 = *(pQformat++); + sfbWidth = tmp1 - stop_idx; + + if (sfbWidth < 2) + { + break; /* will lead to error condition */ + } + + stop_idx += sfbWidth; + + shift_amt = tmp2 - min_q; + + if (shift_amt == 0) + { + Int32 tmp1, tmp2; + tmp1 = *(pCoef++); + tmp2 = *(pCoef++); + /* + * sfbWidth is always an even number + * (check tables in pg.66 IS0 14496-3) + */ + for (Int i = (sfbWidth >> 1) - 1; i != 0; i--) + { + max |= (tmp1 >> 31) ^ tmp1; + max |= (tmp2 >> 31) ^ tmp2; + tmp1 = *(pCoef++); + tmp2 = *(pCoef++); + } + max |= (tmp1 >> 31) ^ tmp1; + max |= (tmp2 >> 31) ^ tmp2; + + } + else + { + if (shift_amt < 31) + { + Int32 tmp1, tmp2; + tmp1 = *(pCoef++) >> shift_amt; + tmp2 = *(pCoef--) >> shift_amt; + /* + * sfbWidth is always an even number + * (check tables in pg.66 IS0 14496-3) + */ + for (Int i = (sfbWidth >> 1) - 1; i != 0; i--) + { + *(pCoef++) = tmp1; + *(pCoef++) = tmp2; + + max |= (tmp1 >> 31) ^ tmp1; + max |= (tmp2 >> 31) ^ tmp2; + tmp1 = *(pCoef++) >> shift_amt; + tmp2 = *(pCoef--) >> shift_amt; + + } + *(pCoef++) = tmp1; + *(pCoef++) = tmp2; + max |= (tmp1 >> 31) ^ tmp1; + max |= (tmp2 >> 31) ^ tmp2; + + } + else + { + pv_memset(pCoef, 0, sizeof(Int32)*sfbWidth); + pCoef += sfbWidth; + } + } + + abs_max_per_window[win] = max; + + } + + } /* for (win) */ + + return min_q; + +} /* normalize() */ |