📄 sbr_enc_frame_gen.c
字号:
/*//////////////////////////////////////////////////////////////////////////////
//
// INTEL CORPORATION PROPRIETARY INFORMATION
// This software is supplied under the terms of a license agreement or
// nondisclosure agreement with Intel Corporation and may not be copied
// or disclosed except in accordance with the terms of that agreement.
// Copyright(c) 2006 Intel Corporation. All Rights Reserved.
//
*/
#include <ipps.h>
#include <ippac.h>
#include <math.h>
#include "aac_status.h"
#include "sbr_settings.h"
#include "sbr_struct.h"
#include "sbr_freq_tabs.h"
#include "sbr_enc_settings.h"
#include "sbr_enc_api_fp.h"
#include "sbr_enc_own_fp.h"
#ifdef SBR_NEED_LOG
#include "sbr_enc_dbg.h"
#endif
/********************************************************************/
#define MAX_SLOTS 12
/********************************************************************/
static const sSBRFrameInfoState
sbrFrameInfo_FIXFIX_Env1 = {
1,
{0, 16},
{1},
0,
1,
{0, 16},
/* empy data */
1,
{0},
1
};
static const sSBRFrameInfoState
sbrFrameInfo_FIXFIX_Env2 = {
2,
{0, 8, 16},
{1, 1},
0,
2,
{0, 8, 16},
/* empy data */
1,
{0},
1
};
static const sSBRFrameInfoState
sbrFrameInfo_FIXFIX_Env4 = {
4,
{0, 4, 8, 12, 16},
{1, 1, 1, 1},
0,
2,
{0, 8, 16},
/* empy data */
1,
{0},
1
};
static const sSBRFrameInfoState*
sbr_FIXFIX_FrameInfoTabs[] = {
&sbrFrameInfo_FIXFIX_Env1,
&sbrFrameInfo_FIXFIX_Env2,
&sbrFrameInfo_FIXFIX_Env4
};
/********************************************************************/
static Ipp32s sbrencCalcFrameClass(Ipp32s frameClassOld, Ipp32s tranFlag)
{
Ipp32s frameClass = FIXFIX;
switch (frameClassOld) {
case FIXFIX:
if (tranFlag)
frameClass = FIXVAR;// stationary to transient transition
else
frameClass = FIXFIX;// when no transients are present, FIXFIX frames are used
break;
case FIXVAR:
if (tranFlag)
frameClass = VARVAR;// "tight" transients are handeled by VARVAR frames
else
frameClass = VARFIX;// "sparse" transients are handeled by [FIXVAR, VARFIX] pairs
break;
case VARFIX:
if (tranFlag)
frameClass = FIXVAR;
else
frameClass = FIXFIX;// transient to stationary transition
break;
case VARVAR:
if (tranFlag)
frameClass = VARVAR;// "tight" transients are handeled by VARVAR frames
else
frameClass = VARFIX;
break;
}
return frameClass;
}
/********************************************************************/
/* utility functions are used by frame generator */
/********************************************************************/
static void sbrencAddRE2Buf(Ipp32s* pBuf, Ipp32s* lenBuf, Ipp32s val)
{
pBuf[*lenBuf] = val;
(*lenBuf)++;
return;
}
/********************************************************************/
/* AddLE2Buf = Add Left Element To Buffer */
/********************************************************************/
static void sbrencAddLE2Buf(Ipp32s* pBuf, Ipp32s* lenBuf, Ipp32s val)
{
Ipp32s i;
for (i = *lenBuf; i > 0; i--) {
pBuf[i] = pBuf[i - 1];
}
pBuf[0] = val;
(*lenBuf)++;
return;
}
/********************************************************************/
/* AddLB2Buf = Add Left Buffer To Buffer */
/********************************************************************/
static void sbrencAddLB2Buf(Ipp32s *pSrc, Ipp32s lenSrc, Ipp32s *pDst, Ipp32s* lenDst)
{
Ipp32s i;
for (i = lenSrc - 1; i >= 0; i--) {
sbrencAddLE2Buf(pDst, lenDst, pSrc[i]);
}
return;
}
/********************************************************************/
/* subdivides dist by calc segments quant to the lengths */
static void
sbrencCalcSegments(Ipp32s dist0, Ipp32s maxSegment, Ipp32s* nSegments, Ipp32s* segment)
{
Ipp32s dist, curSegment = 1;
*nSegments = 1;
dist = dist0;
while (dist > MAX_SLOTS) {
(*nSegments)++;
curSegment = dist0 / (*nSegments);
curSegment = (Ipp32s) floor ( curSegment * 0.5f);
curSegment = IPP_MIN( maxSegment, 2 * curSegment );
dist = dist0 - ((*nSegments) - 1) * curSegment;
}
*segment = curSegment;
return;
}
/********************************************************************/
static void
sbrencLoadTransientBord(Ipp32s* borders, Ipp32s* lenBord,
Ipp32s* freq_res, Ipp32s* lenFreqRes,
Ipp32s* minBord, Ipp32s* maxBord, Ipp32s tranPos)
{
/* reset vectors */
*lenBord = 0;
*lenFreqRes = 0;
/* fill vecBorders: 3 elements [ tranPos + 4, tranPos + 6, tranPos + 10 ] */
sbrencAddRE2Buf(borders, lenBord, tranPos + 4 );
sbrencAddRE2Buf(borders, lenBord, tranPos + 6 );
sbrencAddRE2Buf(borders, lenBord, tranPos + 10);
/* fill vecFreqRes: 3 elements [ LOW=0, LOW=0, HI=1 ] */
sbrencAddRE2Buf(freq_res, lenFreqRes, LO );
sbrencAddRE2Buf(freq_res, lenFreqRes, LO );
sbrencAddRE2Buf(freq_res, lenFreqRes, HI );
/* patch */
*minBord = borders[ 0 ];
*maxBord = borders[ *lenBord - 1 ];
return;
}
/********************************************************************/
static void sbrencLoadBordPreProc(Ipp32s* borders, Ipp32s* lenBord,
Ipp32s* freqRes, Ipp32s* lenFreqRes,
Ipp32s minBord, Ipp32s rest)
{
Ipp32s segment, nSegments;
Ipp32s bord = minBord;
Ipp32s j;
/* fillHelper( GP.aBorders[0], 8 ) */
sbrencCalcSegments( rest, 8, &nSegments, &segment);
/*
* GP.aBorders = cat(fliplr(aBordersFill), GP.aBorders);
* GP.aFreqRes = cat(ones(length(aBordersFill)), GP.aFreqRes);
*/
for (j = 0; j <= nSegments - 2; j++) {
bord = bord - segment;
sbrencAddLE2Buf(borders, lenBord, bord);
sbrencAddLE2Buf(freqRes, lenFreqRes, HI);
}
return;
}
/********************************************************************/
static void sbrencLoadBordPostProc(Ipp32s tranPos,
Ipp32s* borders, Ipp32s* lenBord,
Ipp32s* freqRes, Ipp32s* lenFreqRes,
Ipp32s* nSegments)
{
Ipp32s segment = 0;
Ipp32s bord = 0;
Ipp32s j = 0;
Ipp32s maxStep = 0;
//****
if (tranPos < 4){
maxStep = 6;
} else if (tranPos == 4 || tranPos == 5) {
maxStep = 4;
} else {
maxStep = 8;
}
bord = borders[ *lenBord - 1 ];
bord = 32 - bord;
/* mandatory patch */
if ( bord <= 0 ) {
*nSegments = 1;
*lenBord = *lenBord - 1;
*lenFreqRes = *lenFreqRes - 1;
return;
}
/* else if( bord > 0 ) */
sbrencCalcSegments(bord, maxStep, nSegments, &segment);
bord = borders[ *lenBord - 1 ];
for (j = 0; j <= *nSegments - 2; j++) {
bord += segment;
sbrencAddRE2Buf(borders, lenBord, bord);
sbrencAddRE2Buf(freqRes, lenFreqRes, HI);
}
}
/********************************************************************/
static void sbrencSplitGrid(Ipp32s* borders, Ipp32s* lenBord,
Ipp32s* freqRes, Ipp32s* lenFreqRes,
Ipp32s tran, /* tran = tranPos + 4 */
Ipp32s* bordersNext, Ipp32s* lenBordNext,
Ipp32s* freqResNext, Ipp32s* lenFreqResNext,
Ipp32s* pIndxTran, Ipp32s* pIndxSplt,
Ipp32s* pIndxTranNext, Ipp32s* pIdxFillNext,
Ipp32s nSegments)
{
Ipp32s iSplit = 0;
Ipp32s iTran = EMPTY_MAPPING;
Ipp32s i, j;
Ipp32s iTranNext;
*lenBordNext = 0;
*lenFreqResNext = 0;
while( (borders[iSplit] < MAX_SLOTS + 4) && (iSplit < *lenBord) ) iSplit++;
for (i = 0; i < *lenBord; i++) {
if (borders[i] >= tran) {
iTran = i;
break;
}
}
for (j = 0, i = iSplit; i < *lenBord; i++, j++) {
bordersNext[j] = borders[i] - 16;
freqResNext[j] = freqRes[i];
(*lenBordNext)++;
(*lenFreqResNext)++;
}
/* mandatory patch */
iTranNext = EMPTY_MAPPING;
if (iTran != EMPTY_MAPPING) {
iTranNext = iTran - iSplit;
}
/* I can't stand it */
*pIdxFillNext = *lenBord - (nSegments - 1) - iSplit;
//---------------------
// return result
*pIndxTran = iTran;
*pIndxSplt = iSplit;
*pIndxTranNext = iTranNext;
//--------------------
return;
}
/********************************************************************/
static void
sbrencConflictResolution (Ipp32s *borders, Ipp32s *lenBord,
Ipp32s minBord,
Ipp32s *freqRes, Ipp32s *lenFreqRes,
Ipp32s *bordersNext, Ipp32s *lenBordNext,
Ipp32s *freqResNext, Ipp32s *lenFreqResNext,
Ipp32s iFillNext,
Ipp32s dmin, Ipp32s dmax,
Ipp32s *nLeftBord)
{
Ipp32s nBordNext, maxBordNext, i;
Ipp32s middleBord;
/* be careful: transfer */
#if 1
if (iFillNext >= 1) {
*lenBordNext = iFillNext;
*lenFreqResNext = iFillNext;
}
#endif
nBordNext = *lenBordNext;
maxBordNext = bordersNext[nBordNext - 1];
middleBord = minBord - maxBordNext;
while (middleBord < 0) {
nBordNext--;
maxBordNext = bordersNext[nBordNext - 1];
middleBord = minBord - maxBordNext;
}
*lenBordNext = nBordNext;
*lenFreqResNext = nBordNext;
*nLeftBord = nBordNext - 1;
//----------------------------
if (middleBord <= dmax) {
if (middleBord >= dmin) {
sbrencAddLB2Buf(bordersNext, *lenBordNext, borders, lenBord);
sbrencAddLB2Buf(freqResNext, *lenFreqResNext, freqRes, lenFreqRes);
} else { /* middleBord > dmin */
if (*lenBordNext > 1) {
sbrencAddLB2Buf(bordersNext, *lenBordNext-1, borders, lenBord);
sbrencAddLB2Buf(freqResNext, *lenFreqResNext - 1, freqRes, lenFreqRes);
*nLeftBord--;
} else {
/* lenBord ==== lenFreqRes */
for (i = 0; i < *lenBord - 1; i++) {
borders[i] = borders[i + 1];
freqRes[i] = freqRes[i + 1];
}
(*lenBord)--;
(*lenFreqRes)--;
sbrencAddLB2Buf(bordersNext, *lenBordNext, borders, lenBord);
sbrencAddLB2Buf(freqResNext, *lenFreqResNext, freqRes, lenFreqRes);
} /* */
} /* */
} else { /* (middleBord > dmax) */
sbrencLoadBordPreProc(borders, lenBord, freqRes, lenFreqRes, minBord, middleBord);
sbrencAddLB2Buf(bordersNext, *lenBordNext, borders, lenBord);
sbrencAddLB2Buf(freqResNext, *lenFreqResNext, freqRes, lenFreqRes);
}
return;
}
/********************************************************************/
static void
sbrencCalcSBRGrid(sSBRGrid* pGridState,
Ipp32s frameClass,
Ipp32s *borders, Ipp32s lenBord,
Ipp32s *freqRes, Ipp32s lenFreqRes,
Ipp32s iSplit, Ipp32s iTran, Ipp32s nLeftBord)
{
Ipp32s i, n, absBordLead, absBordTrail, nRightBord, env;
Ipp32s absBord = 0;
Ipp32s bs_pointer = 0;
Ipp32s rel_bord = 0;
Ipp32s *bs_freq_res = pGridState->bs_freq_res;
Ipp32s *bs_freq_res_LR = pGridState->bs_freq_res_LR;
Ipp32s *bs_rel_bord = pGridState->bs_rel_bord;
Ipp32s *bs_rel_bord_0 = pGridState->bs_rel_bord_0;
Ipp32s *bs_rel_bord_1 = pGridState->bs_rel_bord_1;
/* set all length to ZERO */
Ipp32s len_bs_rel_bord = 0;
Ipp32s len_bs_rel_bord_1 = 0;
Ipp32s len_bs_rel_bord_0 = 0;
switch (frameClass) {
//-----------------------
case FIXVAR:
absBord = borders[iSplit];
i = iSplit;
while (i >= 1) {
rel_bord = borders[i] - borders[i - 1];
sbrencAddRE2Buf(bs_rel_bord, &len_bs_rel_bord, rel_bord);
i--;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -