예제 #1
0
/*!
  \brief   crc interface
  \return  1: CRC OK, 0: CRC check failure
*/
int SbrCrcCheck(HANDLE_FDK_BITSTREAM hBs, /*!< handle to bit-buffer  */
                LONG NrBits)              /*!< max. CRC length       */
{
  int crcResult = 1;
  ULONG NrCrcBits;
  ULONG crcCheckResult;
  LONG NrBitsAvailable;
  ULONG crcCheckSum;

  crcCheckSum = FDKreadBits(hBs, 10);

  NrBitsAvailable = FDKgetValidBits(hBs);
  if (NrBitsAvailable <= 0) {
    return 0;
  }

  NrCrcBits = fixMin((INT)NrBits, (INT)NrBitsAvailable);

  crcCheckResult = getCrc(hBs, NrCrcBits);
  FDKpushBack(hBs, (NrBitsAvailable - FDKgetValidBits(hBs)));

  if (crcCheckResult != crcCheckSum) {
    crcResult = 0;
  }

  return (crcResult);
}
예제 #2
0
/*---------------------------------------------------------------------------------------------
     description:   This function returns a bit from the bitstream according to
read direction. It is called very often, therefore it makes sense to inline it
(runtime).
-----------------------------------------------------------------------------------------------
        input:    - handle to FDK bitstream
                  - reference value marking start of bitfield
                  - pLeftStartOfSegment
                  - pRightStartOfSegment
                  - readDirection
-----------------------------------------------------------------------------------------------
        return:   - bit from bitstream
--------------------------------------------------------------------------------------------
*/
UINT HcrGetABitFromBitstream(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
                             INT *pLeftStartOfSegment,
                             INT *pRightStartOfSegment, UCHAR readDirection) {
  UINT bit;
  INT readBitOffset;

  if (readDirection == FROM_LEFT_TO_RIGHT) {
    readBitOffset = (INT)FDKgetValidBits(bs) - bsAnchor + *pLeftStartOfSegment;
    if (readBitOffset) {
      FDKpushBiDirectional(bs, readBitOffset);
    }

    bit = FDKreadBits(bs, 1);

    *pLeftStartOfSegment += 1;
  } else {
    readBitOffset = (INT)FDKgetValidBits(bs) - bsAnchor + *pRightStartOfSegment;
    if (readBitOffset) {
      FDKpushBiDirectional(bs, readBitOffset);
    }

    /* to be replaced with a brother function of FDKreadBits() */
    bit = FDKreadBits(bs, 1);
    FDKpushBack(bs, 2);

    *pRightStartOfSegment -= 1;
  }

  return (bit);
}
예제 #3
0
/*****************************************************************************

    functionname: FDKaacEnc_encodeSpectralData
    description:  encode spectral data
    returns:      the number of written bits
    input:
    output:

*****************************************************************************/
static INT FDKaacEnc_encodeSpectralData(INT                    *sfbOffset,
                                        SECTION_DATA           *sectionData,
                                        SHORT                  *quantSpectrum,
                                        HANDLE_FDK_BITSTREAM    hBitStream)
{
  INT i,sfb;
  INT dbgVal = FDKgetValidBits(hBitStream);

  for(i=0;i<sectionData->noOfSections;i++)
  {
    if(sectionData->huffsection[i].codeBook != CODE_BOOK_PNS_NO)
    {
      /* huffencode spectral data for this huffsection */
      INT tmp = sectionData->huffsection[i].sfbStart+sectionData->huffsection[i].sfbCnt;
      for(sfb=sectionData->huffsection[i].sfbStart; sfb<tmp; sfb++)
      {
        FDKaacEnc_codeValues(quantSpectrum+sfbOffset[sfb],
                             sfbOffset[sfb+1]-sfbOffset[sfb],
                             sectionData->huffsection[i].codeBook,
                             hBitStream);
      }
    }
  }
  return(FDKgetValidBits(hBitStream)-dbgVal);
}
예제 #4
0
int dabWrite_EncodeHeader(HANDLE_DAB hDab,
                                 HANDLE_FDK_BITSTREAM hBitStream,
                                 int buffer_fullness,
                                 int frame_length)
{
  INT crcIndex = 0;


  FDK_ASSERT(((frame_length+hDab->headerBits)/8)<0x2000);      /*13 bit*/
  FDK_ASSERT(buffer_fullness<0x800);    /* 11 bit   */

  FDKcrcReset(&hDab->crcInfo);


//  fprintf(stderr, "dabWrite_EncodeHeader() hDab->currentBlock=%d, frame_length=%d, buffer_fullness=%d\n",
//		  hDab->currentBlock, frame_length, buffer_fullness);

//  if (hDab->currentBlock == 0) {
//	//hDab->subFrameStartPrev=dabWrite_GetHeaderBits(hDab);
//	fprintf(stderr, "header bits[%d] [%d]\n", hDab->subFrameStartPrev, hDab->subFrameStartPrev >> 3);
//    FDKresetBitbuffer(hBitStream, BS_WRITER);
//  }

  //hDab->subFrameStartBit = FDKgetValidBits(hBitStream);
//  fprintf(stderr, "dabWrite_EncodeHeader() hDab->subFrameStartBit=%d [%d]\n", hDab->subFrameStartBit, hDab->subFrameStartBit >> 3);

  //hDab->subFrameStartBit = FDKgetValidBits(hBitStream);
  /* Skip new header if this is raw data block 1..n */
  if (hDab->currentBlock == 0)
  {
    FDKresetBitbuffer(hBitStream, BS_WRITER);
//    fprintf(stderr, "dabWrite_EncodeHeader() after FDKresetBitbuffer=%d [%d]\n", FDKgetValidBits(hBitStream), FDKgetValidBits(hBitStream) >> 3);

    /* fixed header */
    FDKwriteBits(hBitStream, 0, 16); //header_firecode
    FDKwriteBits(hBitStream, 0, 1); //rfa
    FDKwriteBits(hBitStream, hDab->dac_rate, 1);
    FDKwriteBits(hBitStream, hDab->sbr_flag, 1);
    FDKwriteBits(hBitStream, hDab->aac_channel_mode, 1);
    FDKwriteBits(hBitStream, hDab->ps_flag, 1);
    FDKwriteBits(hBitStream, hDab->mpeg_surround_config, 3);
    /* variable header */
    int i;
    for(i=0; i<hDab->num_raw_blocks; i++)
    	FDKwriteBits(hBitStream, 0, 12);
    /* padding */
    if (hDab->dac_rate == 0 || hDab->sbr_flag == 0) {
    	FDKwriteBits(hBitStream, 0, 4);
    }
  } /* End of DAB header */

  hDab->subFrameStartBit = FDKgetValidBits(hBitStream);
  FDK_ASSERT(FDKgetValidBits(hBitStream) % 8 == 0); //only aligned header

//  fprintf(stderr, "dabWrite_EncodeHeader() FDKgetValidBits(hBitStream)=%d [%d]\n", FDKgetValidBits(hBitStream), FDKgetValidBits(hBitStream) >> 3);
  return 0;
}
예제 #5
0
static
TRANSPORTDEC_ERROR AudioSpecificConfig_ExtensionParse(CSAudioSpecificConfig *self, HANDLE_FDK_BITSTREAM bs, CSTpCallBacks *cb)
{
  TP_ASC_EXTENSION_ID  lastAscExt, ascExtId = ASCEXT_UNKOWN;
  INT  bitsAvailable = (INT)FDKgetValidBits(bs);

  while (bitsAvailable >= 11)
  {
    lastAscExt = ascExtId;
    ascExtId   = (TP_ASC_EXTENSION_ID)FDKreadBits(bs, 11);
    bitsAvailable -= 11;

    switch (ascExtId) {
    case ASCEXT_SBR:    /* 0x2b7 */
      if ( (self->m_extensionAudioObjectType != AOT_SBR) && (bitsAvailable >= 5) ) {
        self->m_extensionAudioObjectType = getAOT(bs);

        if ( (self->m_extensionAudioObjectType == AOT_SBR)
          || (self->m_extensionAudioObjectType == AOT_ER_BSAC) )
        { /* Get SBR extension configuration */
          self->m_sbrPresentFlag = FDKreadBits(bs, 1);
          bitsAvailable -= 1;

          if ( self->m_sbrPresentFlag == 1 ) {
            self->m_extensionSamplingFrequency = getSampleRate(bs, &self->m_extensionSamplingFrequencyIndex, 4);

            if ((INT)self->m_extensionSamplingFrequency <= 0) {
              return TRANSPORTDEC_PARSE_ERROR;
            }
          }
          if ( self->m_extensionAudioObjectType == AOT_ER_BSAC ) {
            self->m_extensionChannelConfiguration = FDKreadBits(bs, 4);
            bitsAvailable -= 4;
          }
        }
        /* Update counter because of variable length fields (AOT and sampling rate) */
        bitsAvailable = (INT)FDKgetValidBits(bs);
      }
      break;
    case ASCEXT_PS:     /* 0x548 */
      if ( (lastAscExt == ASCEXT_SBR)
        && (self->m_extensionAudioObjectType == AOT_SBR)
        && (bitsAvailable > 0) )
      { /* Get PS extension configuration */
        self->m_psPresentFlag = FDKreadBits(bs, 1);
        bitsAvailable -= 1;
      }
      break;
    default:
      /* Just ignore anything. */
      return TRANSPORTDEC_OK;
    }
  }

  return TRANSPORTDEC_OK;
}
예제 #6
0
/*
 * Read the extension for height info.
 * return 0 if successfull or -1 if the CRC failed.
 */
static
int CProgramConfig_ReadHeightExt(
                                  CProgramConfig *pPce,
                                  HANDLE_FDK_BITSTREAM bs,
                                  int * const bytesAvailable,
                                  const UINT alignmentAnchor
                                )
{
  int err = 0;
  FDK_CRCINFO crcInfo;    /* CRC state info */
  INT crcReg;
  FDKcrcInit(&crcInfo, 0x07, 0xFF, 8);
  crcReg = FDKcrcStartReg(&crcInfo, bs, 0);
  UINT startAnchor = FDKgetValidBits(bs);

  FDK_ASSERT(pPce != NULL);
  FDK_ASSERT(bs != NULL);
  FDK_ASSERT(bytesAvailable != NULL);

  if ( (startAnchor >= 24) && (*bytesAvailable >= 3)
    && (FDKreadBits(bs,8) == PCE_HEIGHT_EXT_SYNC) )
  {
    int i;

    for (i=0; i < pPce->NumFrontChannelElements; i++)
    {
      pPce->FrontElementHeightInfo[i] = (UCHAR) FDKreadBits(bs,2);
    }
    for (i=0; i < pPce->NumSideChannelElements; i++)
    {
      pPce->SideElementHeightInfo[i] = (UCHAR) FDKreadBits(bs,2);
    }
    for (i=0; i < pPce->NumBackChannelElements; i++)
    {
      pPce->BackElementHeightInfo[i] = (UCHAR) FDKreadBits(bs,2);
    }
    FDKbyteAlign(bs, alignmentAnchor);

    FDKcrcEndReg(&crcInfo, bs, crcReg);
    if ((USHORT)FDKreadBits(bs,8) != FDKcrcGetCRC(&crcInfo)) {
      /* CRC failed */
      err = -1;
    }
  }
  else {
    /* No valid extension data found -> restore the initial bitbuffer state */
    FDKpushBack(bs, startAnchor - FDKgetValidBits(bs));
  }

  /* Always report the bytes read. */
  *bytesAvailable -= (startAnchor - FDKgetValidBits(bs)) >> 3;

  return (err);
}
예제 #7
0
INT transportDec_GetAuBitsRemaining( const HANDLE_TRANSPORTDEC hTp, const UINT layer )
{
  INT bits;

  if (hTp->accessUnitAnchor[layer] > 0 && hTp->auLength[layer] > 0) {
    bits = hTp->auLength[layer] - (hTp->accessUnitAnchor[layer] - FDKgetValidBits(&hTp->bitStream[layer]));
  } else {
    bits = FDKgetValidBits(&hTp->bitStream[layer]);
  }

  return bits;
}
예제 #8
0
/*****************************************************************************

    functionname: FDKaacEnc_encodeSectionData
    description:  encode section data (common Huffman codebooks for adjacent
                  SFB's)
    returns:      none
    input:
    output:

*****************************************************************************/
static INT FDKaacEnc_encodeSectionData(SECTION_DATA *sectionData,
                                       HANDLE_FDK_BITSTREAM hBitStream,
                                       UINT useVCB11)
{
  if (hBitStream != NULL) {
    INT sectEscapeVal=0,sectLenBits=0;
    INT sectLen;
    INT i;
    INT dbgVal=FDKgetValidBits(hBitStream);
    INT sectCbBits = 4;

    switch(sectionData->blockType)
    {
    case LONG_WINDOW:
    case START_WINDOW:
    case STOP_WINDOW:
      sectEscapeVal = SECT_ESC_VAL_LONG;
      sectLenBits   = SECT_BITS_LONG;
      break;

    case SHORT_WINDOW:
      sectEscapeVal = SECT_ESC_VAL_SHORT;
      sectLenBits   = SECT_BITS_SHORT;
      break;
    }

    for(i=0;i<sectionData->noOfSections;i++)
    {
      INT codeBook = sectionData->huffsection[i].codeBook;

      FDKwriteBits(hBitStream,codeBook,sectCbBits);

      {
        sectLen = sectionData->huffsection[i].sfbCnt;

        while(sectLen >= sectEscapeVal)
        {
          FDKwriteBits(hBitStream,sectEscapeVal,sectLenBits);
          sectLen-=sectEscapeVal;
        }
        FDKwriteBits(hBitStream,sectLen,sectLenBits);
      }
    }
    return(FDKgetValidBits(hBitStream)-dbgVal);
  }
  return (0);
}
예제 #9
0
INT FDKsbrEnc_CountSbrChannelPairElement(
    HANDLE_SBR_HEADER_DATA sbrHeaderData,
    HANDLE_PARAMETRIC_STEREO hParametricStereo,
    HANDLE_SBR_BITSTREAM_DATA sbrBitstreamData,
    HANDLE_SBR_ENV_DATA sbrEnvDataLeft, HANDLE_SBR_ENV_DATA sbrEnvDataRight,
    HANDLE_COMMON_DATA cmonData, UINT sbrSyntaxFlags) {
  INT payloadBits;
  INT bitPos = FDKgetValidBits(&cmonData->sbrBitbuf);

  payloadBits = FDKsbrEnc_WriteEnvChannelPairElement(
      sbrHeaderData, hParametricStereo, sbrBitstreamData, sbrEnvDataLeft,
      sbrEnvDataRight, cmonData, sbrSyntaxFlags);

  FDKpushBack(&cmonData->sbrBitbuf,
              (FDKgetValidBits(&cmonData->sbrBitbuf) - bitPos));

  return payloadBits;
}
예제 #10
0
TRANSPORTDEC_ERROR adifRead_DecodeHeader(
        CAdifHeader          *pAdifHeader,
        CProgramConfig       *pPce,
        HANDLE_FDK_BITSTREAM  bs
        )
{
  int i;
  TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
  UINT startAnchor = FDKgetValidBits(bs);

  if ((INT)startAnchor < MIN_ADIF_HEADERLENGTH) {
    return (TRANSPORTDEC_NOT_ENOUGH_BITS);
  }

  if (FDKreadBits(bs,8) != 'A') {
    return (TRANSPORTDEC_SYNC_ERROR);
  }
  if (FDKreadBits(bs,8) != 'D') {
    return (TRANSPORTDEC_SYNC_ERROR);
  }
  if (FDKreadBits(bs,8) != 'I') {
    return (TRANSPORTDEC_SYNC_ERROR);
  }
  if (FDKreadBits(bs,8) != 'F') {
    return (TRANSPORTDEC_SYNC_ERROR);
  }

  if ( (pAdifHeader->CopyrightIdPresent = FDKreadBits(bs,1)) != 0 )
    FDKpushBiDirectional(bs,72);  /* CopyrightId */


  pAdifHeader->OriginalCopy = FDKreadBits(bs,1);
  pAdifHeader->Home = FDKreadBits(bs,1);
  pAdifHeader->BitstreamType = FDKreadBits(bs,1);

  /* pAdifHeader->BitRate = FDKreadBits(bs, 23); */
  pAdifHeader->BitRate = FDKreadBits(bs,16);
  pAdifHeader->BitRate <<= 7;
  pAdifHeader->BitRate |= FDKreadBits(bs,7);

  pAdifHeader->NumProgramConfigElements = FDKreadBits(bs,4) + 1;

  if (pAdifHeader->BitstreamType == 0) {
    FDKpushBiDirectional(bs,20);  /* adif_buffer_fullness */
  }

  /* Parse all PCEs but keep only one */
  for (i=0; i < pAdifHeader->NumProgramConfigElements; i++)
  {
    CProgramConfig_Read(pPce, bs, startAnchor);
  }

  FDKbyteAlign(bs, startAnchor);

  return (ErrorStatus);
}
예제 #11
0
int adifWrite_EncodeHeader(ADIF_INFO *adif,
                                 HANDLE_FDK_BITSTREAM hBs,
                                 INT adif_buffer_fullness)
{
  /* ADIF/PCE/ADTS definitions */
  const char adifId[5]="ADIF";
  const int  copyRightIdPresent=0;
  const int  originalCopy=0;
  const int  home=0;

  int i;

  INT sampleRate = adif->samplingRate;
  INT totalBitRate = adif->bitRate;

  if (adif->headerWritten)
    return 0;

  /* Align inside PCE with respect to the first bit of the header */
  UINT alignAnchor = FDKgetValidBits(hBs);

  /* Signal variable bitrate if buffer fullnes exceeds 20 bit */
  adif->bVariableRate = ( adif_buffer_fullness >= (INT)(0x1<<20) ) ? 1 : 0;

  FDKwriteBits(hBs, adifId[0],8);
  FDKwriteBits(hBs, adifId[1],8);
  FDKwriteBits(hBs, adifId[2],8);
  FDKwriteBits(hBs, adifId[3],8);


  FDKwriteBits(hBs, copyRightIdPresent ? 1:0,1);

  if(copyRightIdPresent) {
    for(i=0;i<72;i++) {
      FDKwriteBits(hBs,0,1);
    }
  }
  FDKwriteBits(hBs, originalCopy ? 1:0,1);
  FDKwriteBits(hBs, home ? 1:0,1);
  FDKwriteBits(hBs, adif->bVariableRate?1:0, 1);
  FDKwriteBits(hBs, totalBitRate,23);

  /* we write only one PCE at the moment */
  FDKwriteBits(hBs, 0, 4);

  if(!adif->bVariableRate) {
    FDKwriteBits(hBs, adif_buffer_fullness, 20);
  }

  /* Write PCE */
  transportEnc_writePCE(hBs, adif->cm, sampleRate, adif->instanceTag, adif->profile, 0, 0, alignAnchor);

  return 0;
}
예제 #12
0
TRANSPORTENC_ERROR transportEnc_GetFrame(HANDLE_TRANSPORTENC hTpEnc, int *nbytes)
{
  HANDLE_FDK_BITSTREAM hBs = &hTpEnc->bitStream;

  switch (hTpEnc->transportFmt) {
    case TT_MP4_LATM_MCP0:
    case TT_MP4_LATM_MCP1:
    case TT_MP4_LOAS:
      *nbytes = hTpEnc->bsBufferSize;
      transportEnc_LatmGetFrame(&hTpEnc->writer.latm, hBs, nbytes);
      break;
    case TT_MP4_ADTS:
      if (hTpEnc->writer.adts.currentBlock >= hTpEnc->writer.adts.num_raw_blocks+1) {
        *nbytes = (FDKgetValidBits(hBs) + 7)>>3;
        hTpEnc->writer.adts.currentBlock = 0;
      } else {
예제 #13
0
static INT getSampleRate(HANDLE_FDK_BITSTREAM bs, UCHAR *index, int nBits)
{
  INT sampleRate;
  int idx;

  idx = FDKreadBits(bs, nBits);
  if( idx == (1<<nBits)-1 ) {
    if(FDKgetValidBits(bs) < 24) {
      return 0;
    }
    sampleRate = FDKreadBits(bs,24);
  } else {
    sampleRate = SamplingRateTable[idx];
  }

  *index = idx;

  return sampleRate;
}
예제 #14
0
TRANSPORTDEC_ERROR transportDec_CrcCheck(HANDLE_TRANSPORTDEC pTp)
{
  switch (pTp->transportFmt) {
  case TT_MP4_ADTS:
    if ( (pTp->parser.adts.bs.num_raw_blocks > 0) && (pTp->parser.adts.bs.protection_absent == 0) )
    {
      HANDLE_FDK_BITSTREAM hBs = &pTp->bitStream[0];
      int bitDiff;
      
      /* Calculate possible offset to CRC value. */
      bitDiff  = pTp->parser.adts.rawDataBlockDist[pTp->parser.adts.bs.num_raw_blocks-pTp->numberOfRawDataBlocks]<<3;
      bitDiff -= pTp->globalFramePos - FDKgetValidBits(hBs) + 16;
      FDKpushBiDirectional(hBs, bitDiff);
      pTp->parser.adts.crcReadValue = FDKreadBits(hBs, 16);
    }
    return adtsRead_CrcCheck(&pTp->parser.adts);
  default:
    return TRANSPORTDEC_OK;
  }
}
예제 #15
0
/**
 * \brief adjust bit stream position and the end of an access unit.
 * \param hTp transport decoder handle.
 * \return error code.
 */
static
TRANSPORTDEC_ERROR transportDec_AdjustEndOfAccessUnit(HANDLE_TRANSPORTDEC hTp)
{
  HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream[0];
  TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;

  switch (hTp->transportFmt) {
    case TT_MP4_LOAS:
    case TT_MP4_LATM_MCP0:
    case TT_MP4_LATM_MCP1:
      if ( hTp->numberOfRawDataBlocks == 0 )
      {
        /* Check global frame length */
        if (hTp->transportFmt == TT_MP4_LOAS && hTp->parser.latm.m_audioMuxLengthBytes > 0)
        {
          int loasOffset;

          loasOffset = (hTp->parser.latm.m_audioMuxLengthBytes*8 + FDKgetValidBits(hBs)) - hTp->globalFramePos;
          if (loasOffset != 0) {
            FDKpushBiDirectional(hBs, loasOffset);
            /* For ELD and other payloads there is an unknown amount of padding, so ignore unread bits, but
               throw an error only if too many bits where read. */
            if (loasOffset < 0) {
              err = TRANSPORTDEC_PARSE_ERROR;
            }
          }
        }

        /* Do global LOAS/LATM audioMuxElement byte alignment */
        FDKbyteAlign(hBs, hTp->globalFramePos);
      }
      break;
    default:
      break;
  }

  return err;
}
예제 #16
0
TRANSPORTDEC_ERROR DrmRawSdcAudioConfig_Parse(
        CSAudioSpecificConfig *self,
        HANDLE_FDK_BITSTREAM   bs
        )
{
  TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;

  AudioSpecificConfig_Init(self);

  if ((INT)FDKgetValidBits(bs) < 20) {
    ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
    goto bail;
  }
  else {
    /* DRM - Audio information data entity - type 9
       - Short Id            2 bits
       - Stream Id           2 bits
       - audio coding        2 bits
       - SBR flag            1 bit
       - audio mode          2 bits
       - audio sampling rate 3 bits
       - text flag           1 bit
       - enhancement flag    1 bit
       - coder field         5 bits
       - rfa                 1 bit  */

    int audioCoding, audioMode, cSamplingFreq, coderField, sfIdx, sbrFlag;

    /* Read the SDC field */
    FDKreadBits(bs,4);   /* Short and Stream Id */

    audioCoding   = FDKreadBits(bs, 2);
    sbrFlag       = FDKreadBits(bs, 1);
    audioMode     = FDKreadBits(bs, 2);
    cSamplingFreq = FDKreadBits(bs, 3);    /* audio sampling rate */

    FDKreadBits(bs, 2);  /* Text and enhancement flag */
    coderField   = FDKreadBits(bs, 5);
    FDKreadBits(bs, 1);  /* rfa */

    /* Evaluate configuration and fill the ASC */
    switch (cSamplingFreq) {
    case 0: /*  8 kHz */
      sfIdx = 11;
      break;
    case 1: /* 12 kHz */
      sfIdx = 9;
      break;
    case 2: /* 16 kHz */
      sfIdx = 8;
      break;
    case 3: /* 24 kHz */
      sfIdx = 6;
      break;
    case 5: /* 48 kHz */
      sfIdx = 3;
      break;
    case 4: /* reserved */
    case 6: /* reserved */
    case 7: /* reserved */
    default:
      ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
      goto bail;
    }

    self->m_samplingFrequencyIndex = sfIdx;
    self->m_samplingFrequency = SamplingRateTable[sfIdx];

    if ( sbrFlag ) {
      UINT i;
      int tmp = -1;
      self->m_sbrPresentFlag = 1;
      self->m_extensionAudioObjectType = AOT_SBR;
      self->m_extensionSamplingFrequency = self->m_samplingFrequency << 1;
      for (i=0; i<(sizeof(SamplingRateTable)/sizeof(SamplingRateTable[0])); i++){
        if (SamplingRateTable[i] == self->m_extensionSamplingFrequency){
          tmp = i;
          break;
        }
      }
      self->m_extensionSamplingFrequencyIndex = tmp;
    }

    switch (audioCoding) {
      case 0: /* AAC */
          self->m_aot = AOT_DRM_AAC     ;  /* Set pseudo AOT for Drm AAC */

        switch (audioMode) {
        case 1: /* parametric stereo */
          self->m_psPresentFlag = 1;
        case 0: /* mono */
          self->m_channelConfiguration = 1;
          break;
        case 2: /* stereo */
          self->m_channelConfiguration = 2;
          break;
        default:
          ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
          goto bail;
        }
        self->m_vcb11Flag = 1;
        self->m_hcrFlag = 1;
        self->m_samplesPerFrame = 960;
        self->m_epConfig = 1;
        break;
      case 1: /* CELP */
        self->m_aot = AOT_ER_CELP;
        self->m_channelConfiguration = 1;
        break;
      case 2: /* HVXC */
        self->m_aot = AOT_ER_HVXC;
        self->m_channelConfiguration = 1;
        break;
      case 3: /* reserved */
      default:
        ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
        self->m_aot = AOT_NONE;
        break;
    }

    if (self->m_psPresentFlag && !self->m_sbrPresentFlag) {
      ErrorStatus = TRANSPORTDEC_PARSE_ERROR;
      goto bail;
    }
  }

bail:
  return (ErrorStatus);
}
예제 #17
0
void dabWrite_EndRawDataBlock(HANDLE_DAB hDab,
                          HANDLE_FDK_BITSTREAM hBs,
                          int *pBits)
{
    FDK_BITSTREAM bsWriter;
	INT crcIndex = 0;
	USHORT crcData;
	INT writeBits=0;
	INT writeBitsNonLastBlock=0;
	INT writeBitsLastBlock=0;
#if 1
    if (hDab->currentBlock == hDab->num_raw_blocks) {
    	//calculate byte-alignment before writing ID_FIL
    	if((FDKgetValidBits(hBs)+3) % 8){
    		writeBits = 8 - ((FDKgetValidBits(hBs)+3) % 8);
    	}

    	INT offset_end = hDab->subchannels_num*110*8 - 2*8 - 3;
    	writeBitsLastBlock = offset_end - FDKgetValidBits(hBs);
        dabWrite_FillRawDataBlock(hBs, writeBitsLastBlock);
		FDKsyncCache(hBs);
		//fprintf(stderr, "FIL-element written=%d\n", writeBitsLastBlock);
		writeBitsLastBlock=writeBits;
    }
#endif
	FDKwriteBits(hBs, 7, 3); //finalize AU: ID_END
	FDKsyncCache(hBs);
	//byte-align (if ID_FIL doesn't align it).
	if(FDKgetValidBits(hBs) % 8){
		writeBits = 8 - (FDKgetValidBits(hBs) % 8);
        FDKwriteBits(hBs, 0x00, writeBits);
		FDKsyncCache(hBs);
	}

	//fake-written bits alignment for last AU
	if (hDab->currentBlock == hDab->num_raw_blocks)
		writeBits=writeBitsLastBlock;

	INT frameLen = (FDKgetValidBits(hBs) - hDab->subFrameStartBit) >> 3;
	//fprintf(stderr, "frame=%d, offset writeBits=%d\n", frameLen, writeBits);

	FDK_ASSERT(FDKgetValidBits(hBs) % 8 == 0); //only aligned au's
    FDK_ASSERT(hDab->subchannels_num*110*8 >= FDKgetValidBits(hBs)+2*8); //don't overlap superframe

    FDKinitBitStream(&bsWriter, hBs->hBitBuf.Buffer, hBs->hBitBuf.bufSize, 0, BS_WRITER);
    FDKpushFor(&bsWriter, hDab->subFrameStartBit);
    FDKcrcReset(&hDab->crcInfo);
    hDab->crcIndex = FDKcrcStartReg(&hDab->crcInfo, &bsWriter, 0);
#if 0
    if (hDab->currentBlock == hDab->num_raw_blocks) {
		INT offset_size = hDab->subchannels_num*110*8 - 2*8 - FDKgetValidBits(hBs);
		//fprintf(stderr, "offset_size=%d\n", offset_size >> 3);
		FDKpushFor(hBs, offset_size);
    }
#endif

    FDKpushFor(&bsWriter, FDKgetValidBits(hBs) - hDab->subFrameStartBit);
	FDKcrcEndReg(&hDab->crcInfo,  &bsWriter, hDab->crcIndex);
	crcData = FDKcrcGetCRC(&hDab->crcInfo);
	//fprintf(stderr, "crcData = %04x\n", crcData);
    /* Write inverted CRC of current raw data block */
    FDKwriteBits(hBs, crcData ^ 0xffff, 16);
	FDKsyncCache(hBs);


    /* Write distance to current data block */
	if(hDab->currentBlock) {
		FDKinitBitStream(&bsWriter, hBs->hBitBuf.Buffer, hBs->hBitBuf.bufSize, 0, BS_WRITER);
	    FDKpushFor(&bsWriter, 24 + (hDab->currentBlock-1)*12);
		//fprintf(stderr, "FDKwriteBits() = %d\n", hDab->subFrameStartBit>>3);
		FDKwriteBits(&bsWriter, (hDab->subFrameStartBit>>3), 12);
		FDKsyncCache(&bsWriter);
	}
예제 #18
0
/**
 * \brief Synchronize to stream and estimate the amount of missing access units due
 *        to a current synchronization error in case of constant average bit rate.
 */
static
TRANSPORTDEC_ERROR transportDec_readStream ( HANDLE_TRANSPORTDEC hTp, const UINT layer )
{

  TRANSPORTDEC_ERROR error = TRANSPORTDEC_OK;
  HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream[layer];
  INT nAU = -1;
  INT headerBits;
  INT bitDistance, bfDelta;

  /* Obtain distance to next synch word */
  bitDistance = FDKgetValidBits(hBs);
  error = synchronization(hTp, &headerBits);
  bitDistance -= FDKgetValidBits(hBs);


  FDK_ASSERT(bitDistance >= 0);

  if (error == TRANSPORTDEC_SYNC_ERROR || (hTp->flags & TPDEC_LOST_FRAMES_PENDING))
  {
    /* Check if estimating lost access units is feasible. */
    if (hTp->avgBitRate > 0 && hTp->asc[0].m_samplesPerFrame > 0 && hTp->asc[0].m_samplingFrequency > 0)
    {
      if (error == TRANSPORTDEC_OK)
      {
        int aj;

        aj = transportDec_GetBufferFullness(hTp);
        if (aj > 0) {
          bfDelta = aj;
        } else {
          bfDelta = 0;
        }
        /* sync was ok: last of a series of bad access units. */
        hTp->flags &= ~TPDEC_LOST_FRAMES_PENDING;
        /* Add up bitDistance until end of the current frame. Later we substract
           this frame from the grand total, since this current successfully synchronized
           frame should not be skipped of course; but it must be accounted into the
           bufferfulness math. */
        bitDistance += hTp->auLength[0];
      } else {
        if ( !(hTp->flags & TPDEC_LOST_FRAMES_PENDING) ) {
          /* sync not ok: one of many bad access units. */
          hTp->flags |= TPDEC_LOST_FRAMES_PENDING;
          bfDelta = - (INT)hTp->lastValidBufferFullness;
        } else {
          bfDelta = 0;
        }
      }

      {
        int num, denom;

        /* Obtain estimate of number of lost frames */
        num = hTp->asc[0].m_samplingFrequency * (bfDelta + bitDistance) + hTp->remainder;
        denom = hTp->avgBitRate * hTp->asc[0].m_samplesPerFrame;
        if (num > 0) {
          nAU = num / denom;
          hTp->remainder = num % denom;
        } else {
          hTp->remainder = num;
        }

        if (error == TRANSPORTDEC_OK)
        {
          /* Final adjustment of remainder, taken -1 into account because current
             frame should not be skipped, thus substract -1 or do nothing instead
             of +1-1 accordingly. */
          if ( (denom - hTp->remainder) >= hTp->remainder ) {
            nAU--;
          }
            
          if (nAU < 0) {
            /* There was one frame too much concealed, so unfortunately we will have to skip one good frame. */
            transportDec_EndAccessUnit(hTp);
            error = synchronization(hTp, &headerBits);             
            nAU = -1;
#ifdef DEBUG
            FDKprintf("ERROR: Bufferfullness accounting failed. remainder=%d, nAU=%d\n", hTp->remainder, nAU);
#endif
          }
          hTp->remainder = 0;
          /* Enforce last missed frames to be concealed. */
          if (nAU > 0) {
            FDKpushBack(hBs, headerBits);
          }
        }
      }
    }
  }

  /* Be sure that lost frames are handled correctly. This is necessary due to some
     sync error sequences where later it turns out that there is not enough data, but
     the bits upto the sync word are discarded, thus causing a value of nAU > 0 */
  if (nAU > 0) {
    error = TRANSPORTDEC_SYNC_ERROR;
  }

  hTp->missingAccessUnits = nAU;

  return error;
}
int transportEnc_writeASC (
                            HANDLE_FDK_BITSTREAM asc,
                            CODER_CONFIG *config,
                            CSTpCallBacks *cb
                           )
{
  UINT extFlag = 0;
  int err;
  int epConfig = 0;

  /* Required for the PCE. */
  UINT alignAnchor = FDKgetValidBits(asc);

  /* Extension Flag: Shall be 1 for aot = 17,19,20,21,22,23,39 */
  switch (config->aot) {
    case AOT_ER_AAC_LC:
    case AOT_ER_AAC_LTP:
    case AOT_ER_AAC_SCAL:
    case AOT_ER_TWIN_VQ:
    case AOT_ER_BSAC:
    case AOT_ER_AAC_LD:
    case AOT_ER_AAC_ELD:
    case AOT_USAC:
        extFlag = 1;
        break;
    default:
        break;
  }

  if (config->extAOT == AOT_SBR || config->extAOT == AOT_PS)
    writeAot(asc, config->extAOT);
  else
    writeAot(asc, config->aot);

  {
    writeSampleRate(asc, config->samplingRate);
  }

  /* Try to guess a reasonable channel mode if not given */
  if (config->channelMode == MODE_INVALID) {
    config->channelMode = transportEnc_GetChannelMode(config->noChannels);
    if (config->channelMode == MODE_INVALID)
      return -1;
  }

  FDKwriteBits( asc, getChannelConfig(config->channelMode), 4 );

  if (config->extAOT == AOT_SBR || config->extAOT == AOT_PS) {
    writeSampleRate(asc, config->extSamplingRate);
    writeAot(asc, config->aot);
  }

  switch (config->aot) {
#ifdef TP_GA_ENABLE
    case AOT_AAC_MAIN:
    case AOT_AAC_LC:
    case AOT_AAC_SSR:
    case AOT_AAC_LTP:
    case AOT_AAC_SCAL:
    case AOT_TWIN_VQ:
    case AOT_ER_AAC_LC:
    case AOT_ER_AAC_LTP:
    case AOT_ER_AAC_SCAL:
    case AOT_ER_TWIN_VQ:
    case AOT_ER_BSAC:
    case AOT_ER_AAC_LD:
      err = transportEnc_writeGASpecificConfig(asc, config, extFlag, alignAnchor);
      if (err)
        return err;
      break;
#endif /* TP_GA_ENABLE */
#ifdef TP_ELD_ENABLE
    case AOT_ER_AAC_ELD:
      err = transportEnc_writeELDSpecificConfig(asc, config, epConfig, cb);
      if (err)
        return err;
      break;
#endif /* TP_ELD_ENABLE */
    default:
      return -1;
  }

  switch (config->aot) {
    case AOT_ER_AAC_LC:
    case AOT_ER_AAC_LTP:
    case AOT_ER_AAC_SCAL:
    case AOT_ER_TWIN_VQ:
    case AOT_ER_BSAC:
    case AOT_ER_AAC_LD:
    case AOT_ER_CELP:
    case AOT_ER_HVXC:
    case AOT_ER_HILN:
    case AOT_ER_PARA:
    case AOT_ER_AAC_ELD:
      FDKwriteBits( asc, 0, 2 ); /* epconfig 0 */
      break;
    default:
      break;
  }

  /* Make sure all bits are sync'ed */
  FDKsyncCache( asc );

  return 0;
}
예제 #20
0
static
TRANSPORTDEC_ERROR synchronization(
        HANDLE_TRANSPORTDEC hTp,
        INT                *pHeaderBits
        )
{
  TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK, errFirstFrame = TRANSPORTDEC_OK;
  HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream[0];

  INT syncLayerFrameBits = 0; /* Length of sync layer frame (i.e. LOAS) */
  INT rawDataBlockLength = 0, rawDataBlockLengthPrevious;
  INT totalBits;
  INT headerBits = 0, headerBitsFirstFrame = 0, headerBitsPrevious;
  INT numFramesTraversed = 0, fTraverseMoreFrames, fConfigFound = (hTp->flags & TPDEC_CONFIG_FOUND), startPosFirstFrame = -1;
  INT numRawDataBlocksFirstFrame = 0, numRawDataBlocksPrevious, globalFramePosFirstFrame = 0, rawDataBlockLengthFirstFrame = 0;
  INT ignoreBufferFullness = hTp->flags & (TPDEC_LOST_FRAMES_PENDING|TPDEC_IGNORE_BUFFERFULLNESS|TPDEC_SYNCOK);

  /* Synch parameters */
  INT syncLength;      /* Length of sync word in bits */
  UINT syncWord;       /* Sync word to be found */
  UINT syncMask;       /* Mask for sync word (for adding one bit, so comprising one bit less) */
  C_ALLOC_SCRATCH_START(contextFirstFrame, transportdec_parser_t, 1);

  totalBits = (INT)FDKgetValidBits(hBs);

  if (totalBits <= 0) {
    err = TRANSPORTDEC_NOT_ENOUGH_BITS;
    goto bail;
  }

  fTraverseMoreFrames = (hTp->flags & (TPDEC_MINIMIZE_DELAY|TPDEC_EARLY_CONFIG)) && ! (hTp->flags & TPDEC_SYNCOK);

  /* Set transport specific sync parameters */
  switch (hTp->transportFmt) {
    case TT_MP4_ADTS:
      syncWord = ADTS_SYNCWORD;
      syncLength = ADTS_SYNCLENGTH;
      break;
    case TT_MP4_LOAS:
      syncWord = 0x2B7;
      syncLength = 11;
      break;
    default:
      syncWord = 0;
      syncLength = 0;
      break;
  }

  syncMask = (1<<syncLength)-1;

  do {
    INT bitsAvail = 0;     /* Bits available in bitstream buffer    */
    INT checkLengthBits;   /* Helper to check remaining bits and buffer boundaries */
    UINT synch;            /* Current sync word read from bitstream */

    headerBitsPrevious = headerBits;

    bitsAvail = (INT)FDKgetValidBits(hBs);

    if (hTp->numberOfRawDataBlocks == 0) {
      /* search synchword */

      FDK_ASSERT( (bitsAvail % TPDEC_SYNCSKIP) == 0);

      if ((bitsAvail-syncLength) < TPDEC_SYNCSKIP) {
        err = TRANSPORTDEC_NOT_ENOUGH_BITS;
        headerBits = 0;
      } else {

        synch = FDKreadBits(hBs, syncLength);

        if ( !(hTp->flags & TPDEC_SYNCOK) ) {
          for (; (bitsAvail-syncLength) >= TPDEC_SYNCSKIP; bitsAvail-=TPDEC_SYNCSKIP) {
            if (synch == syncWord) {
              break;
            }
            synch = ((synch << TPDEC_SYNCSKIP) & syncMask) | FDKreadBits(hBs, TPDEC_SYNCSKIP);
          }
        }
        if (synch != syncWord) {
          /* No correct syncword found. */
          err = TRANSPORTDEC_SYNC_ERROR;
        } else {
          err = TRANSPORTDEC_OK;
        }
        headerBits = syncLength;
      }
    } else {
      headerBits = 0;
    }

    /* Save previous raw data block data */
    rawDataBlockLengthPrevious = rawDataBlockLength;
    numRawDataBlocksPrevious = hTp->numberOfRawDataBlocks;

    /* Parse transport header (raw data block granularity) */

    if (err == TRANSPORTDEC_OK )
    {
      err = transportDec_readHeader(
              hTp,
              hBs,
              syncLength,
              ignoreBufferFullness,
             &rawDataBlockLength,
             &fTraverseMoreFrames,
             &syncLayerFrameBits,
             &fConfigFound,
             &headerBits
              );
    }

    bitsAvail -= headerBits;

    checkLengthBits  = syncLayerFrameBits;

    /* Check if the whole frame would fit the bitstream buffer */
    if (err == TRANSPORTDEC_OK) {
      if ( (checkLengthBits+headerBits) > ((TRANSPORTDEC_INBUF_SIZE<<3)-7) ) {
        /* We assume that the size of the transport bit buffer has been
           chosen to meet all system requirements, thus this condition
           is considered a synchronisation error. */
        err = TRANSPORTDEC_SYNC_ERROR;
      } else {
        if ( bitsAvail < checkLengthBits ) {
          err = TRANSPORTDEC_NOT_ENOUGH_BITS;
        }
      }
    }

    if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
      break;
    }


    if (err == TRANSPORTDEC_SYNC_ERROR) {
      int bits;

      /* Enforce re-sync of transport headers. */
      hTp->numberOfRawDataBlocks = 0;

      /* Ensure that the bit amount lands at a multiple of TPDEC_SYNCSKIP */
      bits = (bitsAvail + headerBits) % TPDEC_SYNCSKIP;
      /* Rewind - TPDEC_SYNCSKIP, in order to look for a synch one bit ahead next time. */
      FDKpushBiDirectional(hBs, -(headerBits - TPDEC_SYNCSKIP) + bits);
      bitsAvail += headerBits - TPDEC_SYNCSKIP - bits;
      headerBits = 0;
    }

    /* Frame traversal */
    if ( fTraverseMoreFrames )
    {
      /* Save parser context for early config discovery "rewind all frames" */
      if ( (hTp->flags & TPDEC_EARLY_CONFIG) && !(hTp->flags & TPDEC_MINIMIZE_DELAY))
      {
        /* ignore buffer fullness if just traversing additional frames for ECD */
        ignoreBufferFullness = 1;

        /* Save context in order to return later */
        if ( err == TRANSPORTDEC_OK && startPosFirstFrame == -1 ) {
          startPosFirstFrame = FDKgetValidBits(hBs);
          numRawDataBlocksFirstFrame = hTp->numberOfRawDataBlocks;
          globalFramePosFirstFrame = hTp->globalFramePos;
          rawDataBlockLengthFirstFrame = rawDataBlockLength;
          headerBitsFirstFrame = headerBits;
          errFirstFrame = err;
          FDKmemcpy(contextFirstFrame, &hTp->parser, sizeof(transportdec_parser_t));
        }

        /* Break when config was found or it is not possible anymore to find a config */
        if (startPosFirstFrame != -1 && (fConfigFound || err != TRANSPORTDEC_OK))
        {
          /* In case of ECD and sync error, do not rewind anywhere. */
          if (err == TRANSPORTDEC_SYNC_ERROR)
          {
            startPosFirstFrame = -1;
            fConfigFound = 0;
            numFramesTraversed = 0;
          }
          break;
        }
      }

      if (err == TRANSPORTDEC_OK) {
        FDKpushFor(hBs, rawDataBlockLength);
        bitsAvail -= rawDataBlockLength;
        numFramesTraversed++;
        /* Ignore error here itentionally. */
        transportDec_AdjustEndOfAccessUnit(hTp);
      }
    }
  } while ( fTraverseMoreFrames || (err == TRANSPORTDEC_SYNC_ERROR && !(hTp->flags & TPDEC_SYNCOK)));

  /* Restore context in case of ECD frame traversal */
  if ( startPosFirstFrame != -1 && (fConfigFound || err != TRANSPORTDEC_OK) ) {
    FDKpushBiDirectional(hBs, FDKgetValidBits(hBs) - startPosFirstFrame);
    FDKmemcpy(&hTp->parser, contextFirstFrame, sizeof(transportdec_parser_t));
    hTp->numberOfRawDataBlocks = numRawDataBlocksFirstFrame;
    hTp->globalFramePos = globalFramePosFirstFrame;
    rawDataBlockLength = rawDataBlockLengthFirstFrame;
    headerBits = headerBitsFirstFrame;
    err = errFirstFrame;
    numFramesTraversed = 0;
  } 

  /* Additional burst data mode buffer fullness check. */
  if ( !(hTp->flags & (TPDEC_LOST_FRAMES_PENDING|TPDEC_IGNORE_BUFFERFULLNESS|TPDEC_SYNCOK)) && err == TRANSPORTDEC_OK) {
    err = additionalHoldOffNeeded(hTp, transportDec_GetBufferFullness(hTp), FDKgetValidBits(hBs) - syncLayerFrameBits);
    if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
      hTp->holdOffFrames++;
    }
  }
  
  /* Rewind for retry because of not enough bits */
  if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
    FDKpushBack(hBs, headerBits);
    headerBits = 0;
  }
  else {
    /* reset hold off frame counter */
    hTp->holdOffFrames = 0;
  }

  /* Return to last good frame in case of frame traversal but not ECD. */
  if (numFramesTraversed > 0) {
    FDKpushBack(hBs, rawDataBlockLengthPrevious);
    if (err != TRANSPORTDEC_OK) {
      hTp->numberOfRawDataBlocks = numRawDataBlocksPrevious;
      headerBits = headerBitsPrevious;
    }
    err = TRANSPORTDEC_OK;
  }

bail:
  hTp->auLength[0] = rawDataBlockLength;

  /* Detect pointless TRANSPORTDEC_NOT_ENOUGH_BITS error case, were the bit buffer is already full,
     or no new burst packet fits. Recover by advancing the bit buffer. */
  if ( (TRANSPORTDEC_NOT_ENOUGH_BITS == err) &&  (FDKgetValidBits(hBs) >= ((TRANSPORTDEC_INBUF_SIZE*8 - ((hTp->avgBitRate*hTp->burstPeriod)/1000)) - 7)) )
  {
    FDKpushFor(hBs, TPDEC_SYNCSKIP);
    err = TRANSPORTDEC_SYNC_ERROR;
  }

  if (err == TRANSPORTDEC_OK) {
    hTp->flags |= TPDEC_SYNCOK;
  }

  if (fConfigFound) {
    hTp->flags |= TPDEC_CONFIG_FOUND;
  }

  if (pHeaderBits != NULL) {
    *pHeaderBits = headerBits;
  }

  if (err == TRANSPORTDEC_SYNC_ERROR) {
    hTp->flags &= ~TPDEC_SYNCOK;
  }

  C_ALLOC_SCRATCH_END(contextFirstFrame, transportdec_parser_t, 1);

  return err;
}
예제 #21
0
void
FDKsbrEnc_AssembleSbrBitstream( HANDLE_COMMON_DATA  hCmonData,
                                HANDLE_FDK_CRCINFO  hCrcInfo,
                                INT                 crcRegion,
                                UINT                sbrSyntaxFlags)
{
  USHORT crcReg =  SBR_CRCINIT;
  INT numCrcBits,i;

  /* check if SBR is present */
  if ( hCmonData==NULL )
    return;

  hCmonData->sbrFillBits = 0; /* Fill bits are written only for GA streams */

  if ( sbrSyntaxFlags & SBR_SYNTAX_DRM_CRC )
  {
    /*
     * Calculate and write DRM CRC
     */
    FDKcrcEndReg( hCrcInfo, &hCmonData->sbrBitbuf, crcRegion );
    FDKwriteBits( &hCmonData->tmpWriteBitbuf, FDKcrcGetCRC(hCrcInfo)^0xFF, SI_SBR_DRM_CRC_BITS );
  }
  else
  {
    if ( !(sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) )
    {
      /* Do alignment here, because its defined as part of the sbr_extension_data */
      int sbrLoad = hCmonData->sbrHdrBits + hCmonData->sbrDataBits;

      if ( sbrSyntaxFlags & SBR_SYNTAX_CRC ) {
        sbrLoad += SI_SBR_CRC_BITS;
      }

      sbrLoad += 4;         /* Do byte Align with 4 bit offset. ISO/IEC 14496-3:2005(E) page 39. */

      hCmonData->sbrFillBits = (8 - (sbrLoad % 8)) % 8;

      /*
        append fill bits
      */
      FDKwriteBits(&hCmonData->sbrBitbuf, 0,  hCmonData->sbrFillBits );

      FDK_ASSERT(FDKgetValidBits(&hCmonData->sbrBitbuf) % 8 == 4);
    }

    /*
      calculate crc
    */
    if ( sbrSyntaxFlags & SBR_SYNTAX_CRC ) {
      FDK_BITSTREAM  tmpCRCBuf = hCmonData->sbrBitbuf;
      FDKresetBitbuffer( &tmpCRCBuf, BS_READER );

      numCrcBits = hCmonData->sbrHdrBits + hCmonData->sbrDataBits + hCmonData->sbrFillBits;

      for(i=0;i<numCrcBits;i++){
        INT bit;
        bit = FDKreadBits(&tmpCRCBuf,1);
        crcAdvance(SBR_CRC_POLY,SBR_CRC_MASK,&crcReg,bit,1);
      }
      crcReg &= (SBR_CRC_RANGE);

      /*
       * Write CRC data.
       */
      FDKwriteBits (&hCmonData->tmpWriteBitbuf, crcReg, SI_SBR_CRC_BITS);
    }
  }

  FDKsyncCache(&hCmonData->tmpWriteBitbuf);
}
예제 #22
0
static INT FDKaacEnc_encodeScaleFactorData(UINT                  *maxValueInSfb,
                                           SECTION_DATA          *sectionData,
                                           INT                   *scalefac,
                                           HANDLE_FDK_BITSTREAM   hBitStream,
                                           INT                   *RESTRICT noiseNrg,
                                           const INT             *isScale,
                                           INT                    globalGain)
{
  if (hBitStream != NULL) {
    INT i,j,lastValScf,deltaScf;
    INT deltaPns;
    INT lastValPns = 0;
    INT noisePCMFlag = TRUE;
    INT lastValIs;

    INT dbgVal = FDKgetValidBits(hBitStream);

    lastValScf=scalefac[sectionData->firstScf];
    lastValPns = globalGain-scalefac[sectionData->firstScf]+globalGainOffset-4*LOG_NORM_PCM-noiseOffset;
    lastValIs  = 0;

    for(i=0; i<sectionData->noOfSections; i++){
      if (sectionData->huffsection[i].codeBook != CODE_BOOK_ZERO_NO) {

        if ((sectionData->huffsection[i].codeBook == CODE_BOOK_IS_OUT_OF_PHASE_NO) ||
            (sectionData->huffsection[i].codeBook == CODE_BOOK_IS_IN_PHASE_NO))
        {
          INT sfbStart = sectionData->huffsection[i].sfbStart;
          INT tmp = sfbStart + sectionData->huffsection[i].sfbCnt;
          for(j=sfbStart; j<tmp; j++) {
            INT deltaIs   = isScale[j]-lastValIs;
예제 #23
0
TRANSPORTENC_ERROR transportEnc_WriteAccessUnit(
                                               HANDLE_TRANSPORTENC hTp,
                                               INT frameUsedBits,
                                               int bufferFullness,
                                               int ncc
                                              )
{
  TRANSPORTENC_ERROR err = TRANSPORTENC_OK;

  if (!hTp) {
    return TRANSPORTENC_INVALID_PARAMETER;
  }
  HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream;

  /* In case of writing PCE in raw_data_block frameUsedBits must be adapted. */
  if (hTp->pceFrameCounter>=hTp->config.headerPeriod) {
    frameUsedBits += transportEnc_GetPCEBits(hTp->config.channelMode, hTp->config.matrixMixdownA, 3); /* Consider 3 bits ID signalling in alignment */
  }

  switch (hTp->transportFmt) {
    case TT_MP4_ADIF:
      FDKinitBitStream(&hTp->bitStream, hTp->bsBuffer, hTp->bsBufferSize, 0, BS_WRITER);
      adifWrite_EncodeHeader(
             &hTp->writer.adif,
              hBs,
              bufferFullness
              );
      break;
    case TT_MP4_ADTS:
      bufferFullness /= ncc;                          /* Number of Considered Channels */
      bufferFullness /= 32;
      bufferFullness = FDKmin(0x7FF, bufferFullness); /* Signal variable rate */
      adtsWrite_EncodeHeader(
             &hTp->writer.adts,
             &hTp->bitStream,
              bufferFullness,
              frameUsedBits
              );
      break;
    case TT_DABPLUS:
      bufferFullness /= ncc;                          /* Number of Considered Channels */
      bufferFullness /= 32;
      bufferFullness = FDKmin(0x7FF, bufferFullness); /* Signal variable rate */
      dabWrite_EncodeHeader(
             &hTp->writer.dab,
             &hTp->bitStream,
              bufferFullness,
              frameUsedBits
              );
      break;
    case TT_MP4_LOAS:
    case TT_MP4_LATM_MCP0:
    case TT_MP4_LATM_MCP1:
      bufferFullness /= ncc;                         /* Number of Considered Channels */
      bufferFullness /= 32;
      bufferFullness = FDKmin(0xFF, bufferFullness); /* Signal variable rate */
      transportEnc_LatmWrite(
             &hTp->writer.latm,
              hBs,
              frameUsedBits,
              bufferFullness,
             &hTp->callbacks
              );
    break;
    case TT_MP4_RAW:
      if (hTp->writer.raw.curSubFrame >= hTp->writer.raw.nSubFrames) {
        hTp->writer.raw.curSubFrame = 0;
        FDKinitBitStream(&hTp->bitStream, hTp->bsBuffer, hTp->bsBufferSize, 0, BS_WRITER);
      }
      hTp->writer.raw.prevBits = FDKgetValidBits(hBs);
      break;
    default:
      err = TRANSPORTENC_UNSUPPORTED_FORMAT;
      break;
  }

  /* Write PCE in raw_data_block if required */
  if (hTp->pceFrameCounter>=hTp->config.headerPeriod) {
    INT crcIndex = 0;
    /* Align inside PCE with repsect to the first bit of the raw_data_block() */
    UINT alignAnchor = FDKgetValidBits(&hTp->bitStream);

    /* Write PCE element ID bits */
    FDKwriteBits(&hTp->bitStream, ID_PCE, 3);

    if ( (hTp->transportFmt==TT_MP4_ADTS) && !hTp->writer.adts.protection_absent) {
      crcIndex = adtsWrite_CrcStartReg(&hTp->writer.adts, &hTp->bitStream, 0);
    }

    /* Write PCE as first raw_data_block element */
    transportEnc_writePCE(&hTp->bitStream, hTp->config.channelMode, hTp->config.samplingRate, 0, 1, hTp->config.matrixMixdownA, hTp->config.flags & CC_PSEUDO_SURROUND, alignAnchor);

    if ( (hTp->transportFmt==TT_MP4_ADTS) && !hTp->writer.adts.protection_absent) {
      adtsWrite_CrcEndReg(&hTp->writer.adts, &hTp->bitStream, crcIndex);
    }
    hTp->pceFrameCounter = 0; /* reset pce frame counter */
  }

  if (hTp->pceFrameCounter!=-1) {
    hTp->pceFrameCounter++; /* Update pceFrameCounter only if PCE writing is active. */
  }

  return err;
}
예제 #24
0
SBR_ERROR sbrDecoder_Parse(
        HANDLE_SBRDECODER self,
        HANDLE_FDK_BITSTREAM  hBs,
        int *count,
        int  bsPayLen,
        int  crcFlag,
        MP4_ELEMENT_ID prevElement,
        int elementIndex,
        int fGlobalIndependencyFlag
        )
{
  SBR_DECODER_ELEMENT   *hSbrElement;
  HANDLE_SBR_HEADER_DATA hSbrHeader;
  HANDLE_SBR_CHANNEL    *pSbrChannel;

  SBR_FRAME_DATA *hFrameDataLeft;
  SBR_FRAME_DATA *hFrameDataRight;

  SBR_ERROR errorStatus = SBRDEC_OK;
  SBR_SYNC_STATE initialSyncState;
  SBR_HEADER_STATUS headerStatus = HEADER_NOT_PRESENT;

  INT  startPos;
  INT  CRCLen = 0;

  int  stereo;
  int  fDoDecodeSbrData = 1;

  int lastSlot, lastHdrSlot = 0, thisHdrSlot;

  /* Remember start position of  SBR element */
  startPos = FDKgetValidBits(hBs);

  /* SBR sanity checks */
  if ( self == NULL || self->pSbrElement[elementIndex] == NULL ) {
    errorStatus = SBRDEC_NOT_INITIALIZED;
    goto bail;
  } 

  hSbrElement = self->pSbrElement[elementIndex];

  lastSlot    = (hSbrElement->useFrameSlot > 0) ? hSbrElement->useFrameSlot-1 : self->numDelayFrames;
  lastHdrSlot =  hSbrElement->useHeaderSlot[lastSlot];
  thisHdrSlot =  getHeaderSlot( hSbrElement->useFrameSlot, hSbrElement->useHeaderSlot );  /* Get a free header slot not used by frames not processed yet. */

  /* Assign the free slot to store a new header if there is one. */
  hSbrHeader = &self->sbrHeader[elementIndex][thisHdrSlot];

  pSbrChannel = hSbrElement->pSbrChannel;
  stereo = (hSbrElement->elementID == ID_CPE) ? 1 : 0;

  hFrameDataLeft  = &self->pSbrElement[elementIndex]->pSbrChannel[0]->frameData[hSbrElement->useFrameSlot];
  hFrameDataRight = &self->pSbrElement[elementIndex]->pSbrChannel[1]->frameData[hSbrElement->useFrameSlot];

  initialSyncState = hSbrHeader->syncState;

  /* reset PS flag; will be set after PS was found */
  self->flags &= ~SBRDEC_PS_DECODED;

  if (hSbrHeader->status & SBRDEC_HDR_STAT_UPDATE) {
    /* Got a new header from extern (e.g. from an ASC) */
    headerStatus = HEADER_OK;
    hSbrHeader->status &= ~SBRDEC_HDR_STAT_UPDATE;
  }
  else if (thisHdrSlot != lastHdrSlot) {
    /* Copy the last header into this slot otherwise the
       header compare will trigger more HEADER_RESETs than needed. */
    copySbrHeader( hSbrHeader, &self->sbrHeader[elementIndex][lastHdrSlot] );
  }

  /*
     Check if bit stream data is valid and matches the element context
  */
  if ( ((prevElement != ID_SCE) && (prevElement != ID_CPE)) || prevElement != hSbrElement->elementID) {
    /* In case of LFE we also land here, since there is no LFE SBR element (do upsampling only) */
    fDoDecodeSbrData = 0;
  }

  if (fDoDecodeSbrData)
  {
    if ((INT)FDKgetValidBits(hBs) <= 0) {
      fDoDecodeSbrData = 0;
    }
  }

  /*
     SBR CRC-check
  */
  if (fDoDecodeSbrData)
  {
    if (crcFlag == 1) {
      switch (self->coreCodec) {
      case AOT_ER_AAC_ELD:
        FDKpushFor (hBs, 10);
        /* check sbrcrc later: we don't know the payload length now */
        break;
      default:
        CRCLen = bsPayLen - 10;                     /* change: 0 => i */
        if (CRCLen < 0) {
          fDoDecodeSbrData = 0;
        } else {
          fDoDecodeSbrData = SbrCrcCheck (hBs, CRCLen);
        }
        break;
      }
    }
  } /* if (fDoDecodeSbrData) */

  /*
     Read in the header data and issue a reset if change occured
  */
  if (fDoDecodeSbrData)
  {
    int sbrHeaderPresent;

    {
      sbrHeaderPresent = FDKreadBit(hBs);
    }

    if ( sbrHeaderPresent ) {
      headerStatus = sbrGetHeaderData (hSbrHeader,
                                       hBs,
                                       self->flags,
                                       1);
    }

    if (headerStatus == HEADER_RESET)
    {
      errorStatus = sbrDecoder_HeaderUpdate(
            self,
            hSbrHeader,
            headerStatus,
            pSbrChannel,
            hSbrElement->nChannels 
            );

      if (errorStatus == SBRDEC_OK) {
        hSbrHeader->syncState = SBR_HEADER;
      } else {
        hSbrHeader->syncState = SBR_NOT_INITIALIZED;
      }
    }

    if (errorStatus != SBRDEC_OK) {
      fDoDecodeSbrData = 0;
    }
  } /* if (fDoDecodeSbrData) */

  /*
    Print debugging output only if state has changed
  */

  /* read frame data */
  if ((hSbrHeader->syncState >= SBR_HEADER) && fDoDecodeSbrData) {
    int sbrFrameOk;
    /* read the SBR element data */
    if (stereo) {
      sbrFrameOk = sbrGetChannelPairElement(hSbrHeader,
                                            hFrameDataLeft,
                                            hFrameDataRight,
                                            hBs,
                                            self->flags,
                                            self->pSbrElement[elementIndex]->transposerSettings.overlap);
    }
    else {
      if (self->hParametricStereoDec != NULL) {
        /* update slot index for PS bitstream parsing */
        self->hParametricStereoDec->bsLastSlot = self->hParametricStereoDec->bsReadSlot;
        self->hParametricStereoDec->bsReadSlot = hSbrElement->useFrameSlot;
      }
      sbrFrameOk = sbrGetSingleChannelElement(hSbrHeader,
                                              hFrameDataLeft,
                                              hBs,
                                              self->hParametricStereoDec,
                                              self->flags,
                                              self->pSbrElement[elementIndex]->transposerSettings.overlap);
    }
    if (!sbrFrameOk) {
      fDoDecodeSbrData = 0;
    }
    else {
      INT valBits;

      if (bsPayLen > 0) {
        valBits = bsPayLen - ((INT)startPos - (INT)FDKgetValidBits(hBs));
      } else {
        valBits = (INT)FDKgetValidBits(hBs);
      }

      if ( crcFlag == 1 ) {
        switch (self->coreCodec) {
        case AOT_ER_AAC_ELD:
          {
            /* late crc check for eld */
            INT payloadbits = (INT)startPos - (INT)FDKgetValidBits(hBs) - startPos;
            INT crcLen      = payloadbits - 10;
            FDKpushBack(hBs, payloadbits);
            fDoDecodeSbrData      = SbrCrcCheck (hBs, crcLen);
            FDKpushFor(hBs, crcLen);
          }
          break;
        default:
          break;
        }
      }

      /* sanity check of remaining bits */
      if (valBits < 0) {
        fDoDecodeSbrData = 0;
      } else {
        switch (self->coreCodec) {
        case AOT_SBR:
        case AOT_PS:
        case AOT_AAC_LC:
          {
            /* This sanity check is only meaningful with General Audio bitstreams */
            int alignBits = valBits & 0x7;

            if (valBits > alignBits) {
              fDoDecodeSbrData = 0;
            }
          }
          break;
        default:
          /* No sanity check available */
          break;
        }
      }
    }
  } else {
    /* The returned bit count will not be the actual payload size since we did not
       parse the frame data. Return an error so that the caller can react respectively. */
    errorStatus = SBRDEC_PARSE_ERROR;
  }

  if (!fDoDecodeSbrData) {
    /* Set error flag for this slot to trigger concealment */
    self->pSbrElement[elementIndex]->frameErrorFlag[hSbrElement->useFrameSlot] = 1;
    errorStatus = SBRDEC_PARSE_ERROR;
  } else {
    /* Everything seems to be ok so clear the error flag */
    self->pSbrElement[elementIndex]->frameErrorFlag[hSbrElement->useFrameSlot] = 0;
  }

  if (!stereo) {
    /* Turn coupling off explicitely to avoid access to absent right frame data
       that might occur with corrupt bitstreams. */
    hFrameDataLeft->coupling = COUPLING_OFF;
  }

bail:
  if (errorStatus == SBRDEC_OK) {
    if (headerStatus == HEADER_NOT_PRESENT) {
      /* Use the old header for this frame */
      hSbrElement->useHeaderSlot[hSbrElement->useFrameSlot] = lastHdrSlot;
    } else {
      /* Use the new header for this frame */
      hSbrElement->useHeaderSlot[hSbrElement->useFrameSlot] = thisHdrSlot;
    }

    /* Move frame pointer to the next slot which is up to be decoded/applied next */
    hSbrElement->useFrameSlot = (hSbrElement->useFrameSlot+1) % (self->numDelayFrames+1);
  }

  *count -= startPos - FDKgetValidBits(hBs);

  return errorStatus;
}
예제 #25
0
static
TRANSPORTDEC_ERROR synchronization(
        HANDLE_TRANSPORTDEC hTp,
        INT                *pHeaderBits
        )
{
  TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK, errFirstFrame = TRANSPORTDEC_OK;
  HANDLE_FDK_BITSTREAM hBs = &hTp->bitStream[0];

  INT syncLayerFrameBits = 0; /* Length of sync layer frame (i.e. LOAS) */
  INT rawDataBlockLength = 0, rawDataBlockLengthPrevious;
  INT totalBits;
  INT headerBits = 0, headerBitsFirstFrame = 0, headerBitsPrevious;
  INT numFramesTraversed = 0, fTraverseMoreFrames, fConfigFound = 0, startPos, startPosFirstFrame = -1;
  INT numRawDataBlocksFirstFrame = 0, numRawDataBlocksPrevious, globalFramePosFirstFrame = 0, rawDataBlockLengthFirstFrame = 0;
  INT ignoreBufferFullness = hTp->flags & (TPDEC_IGNORE_BUFFERFULLNESS|TPDEC_SYNCOK);

  /* Synch parameters */
  INT syncLength;      /* Length of sync word in bits */
  UINT syncWord;       /* Sync word to be found */
  UINT syncMask;       /* Mask for sync word (for adding one bit, so comprising one bit less) */
  C_ALLOC_SCRATCH_START(contextFirstFrame, transportdec_parser_t, 1);

  totalBits = (INT)FDKgetValidBits(hBs);

  if (totalBits <= 0) {
    /* Return sync error, because this happens only in case of severly damaged bit streams.
       Returning TRANSPORTDEC_NOT_ENOUGH_BITS here is very dangerous. */
    /* numberOfRawDataBlocks must be always reset in case of sync errors. */
    hTp->numberOfRawDataBlocks = 0;
    goto bail;
  }

  fTraverseMoreFrames = (hTp->flags & (TPDEC_MINIMIZE_DELAY|TPDEC_EARLY_CONFIG)) && ! (hTp->flags & TPDEC_SYNCOK);

  /* Set transport specific sync parameters */
  switch (hTp->transportFmt) {
    case TT_MP4_ADTS:
      syncWord = ADTS_SYNCWORD;
      syncLength = ADTS_SYNCLENGTH;
      break;
    case TT_MP4_LOAS:
      syncWord = 0x2B7;
      syncLength = 11;
      break;
    default:
      syncWord = 0;
      syncLength = 0;
      break;
  }

  syncMask = (1<<syncLength)-1;

  do {
    INT bitsAvail = 0;     /* Bits available in bitstream buffer    */
    INT checkLengthBits;   /* Helper to check remaining bits and buffer boundaries */
    UINT synch;            /* Current sync word read from bitstream */

    headerBitsPrevious = headerBits;

    bitsAvail = (INT)FDKgetValidBits(hBs);

    if (hTp->numberOfRawDataBlocks == 0) {
      /* search synchword */

      FDK_ASSERT( (bitsAvail % TPDEC_SYNCSKIP) == 0);

      if ((bitsAvail-syncLength) < TPDEC_SYNCSKIP) {
        err = TRANSPORTDEC_NOT_ENOUGH_BITS;
        headerBits = 0;
      } else {

        synch = FDKreadBits(hBs, syncLength);

        if ( !(hTp->flags & TPDEC_SYNCOK) ) {
          for (; (bitsAvail-syncLength) >= TPDEC_SYNCSKIP; bitsAvail-=TPDEC_SYNCSKIP) {
            if (synch == syncWord) {
              break;
            }
            synch = ((synch << TPDEC_SYNCSKIP) & syncMask) | FDKreadBits(hBs, TPDEC_SYNCSKIP);
          }
        }
        if (synch != syncWord) {
          /* No correct syncword found. */
          err = TRANSPORTDEC_SYNC_ERROR;
        } else {
          err = TRANSPORTDEC_OK;
        }
        headerBits = syncLength;
      }
    } else {
      headerBits = 0;
    }

    /* Save previous raw data block data */
    rawDataBlockLengthPrevious = rawDataBlockLength;
    numRawDataBlocksPrevious = hTp->numberOfRawDataBlocks;

    /* Parse transport header (raw data block granularity) */
    startPos = FDKgetValidBits(hBs);

    if (err == TRANSPORTDEC_OK )
    {
      switch (hTp->transportFmt) {
        case TT_MP4_ADTS:
          if (hTp->numberOfRawDataBlocks <= 0)
          {
            int errC;

            /* Parse ADTS header */
            err = adtsRead_DecodeHeader( &hTp->parser.adts, &hTp->asc[0], hBs, ignoreBufferFullness );
            if (err != TRANSPORTDEC_OK) {
              if (err != TRANSPORTDEC_NOT_ENOUGH_BITS) {
                err = TRANSPORTDEC_SYNC_ERROR;
              }
            } else {
              errC = hTp->callbacks.cbUpdateConfig(hTp->callbacks.cbUpdateConfigData, &hTp->asc[0]);
              if (errC != 0) {
                err = TRANSPORTDEC_SYNC_ERROR;
              } else {
                hTp->numberOfRawDataBlocks = hTp->parser.adts.bs.num_raw_blocks+1;
                /* CAUTION: The PCE (if available) is declared to be a part of the header! */
                hTp->globalFramePos = FDKgetValidBits(hBs) + hTp->parser.adts.bs.num_pce_bits;
              }
            }
          }
          else {
            /* Reset CRC because the next bits are the beginning of a raw_data_block() */
            FDKcrcReset(&hTp->parser.adts.crcInfo);
            hTp->globalFramePos = FDKgetValidBits(hBs);
          }
          if (err == TRANSPORTDEC_OK) {
            hTp->numberOfRawDataBlocks--;
            rawDataBlockLength = adtsRead_GetRawDataBlockLength(&hTp->parser.adts, (hTp->parser.adts.bs.num_raw_blocks-hTp->numberOfRawDataBlocks));
            syncLayerFrameBits = (hTp->parser.adts.bs.frame_length<<3) - (startPos - FDKgetValidBits(hBs)) - syncLength;
            if (syncLayerFrameBits <= 0) {
              err = TRANSPORTDEC_SYNC_ERROR;
            }
          } else {
            hTp->numberOfRawDataBlocks = 0;
          }
          break;
        case TT_MP4_LOAS:
          if (hTp->numberOfRawDataBlocks <= 0)
          {
            syncLayerFrameBits = FDKreadBits(hBs, 13);
            hTp->parser.latm.m_audioMuxLengthBytes = syncLayerFrameBits;
            syncLayerFrameBits <<= 3;
          }
        case TT_MP4_LATM_MCP1:
        case TT_MP4_LATM_MCP0:
          if (hTp->numberOfRawDataBlocks <= 0)
          {
            hTp->globalFramePos = FDKgetValidBits(hBs);

            err = CLatmDemux_Read(
                    hBs,
                   &hTp->parser.latm,
                    hTp->transportFmt,
                   &hTp->callbacks,
                    hTp->asc,
                    ignoreBufferFullness);

            if (err != TRANSPORTDEC_OK) {
              if (err != TRANSPORTDEC_NOT_ENOUGH_BITS) {
                err = TRANSPORTDEC_SYNC_ERROR;
              }
            } else {
              hTp->numberOfRawDataBlocks = CLatmDemux_GetNrOfSubFrames(&hTp->parser.latm);
              syncLayerFrameBits -= startPos - FDKgetValidBits(hBs) - (13);            
            }
          } else {
            err = CLatmDemux_ReadPayloadLengthInfo(hBs, &hTp->parser.latm);
            if (err != TRANSPORTDEC_OK) {
              err = TRANSPORTDEC_SYNC_ERROR;
            }
          }
          if (err == TRANSPORTDEC_OK) {
            rawDataBlockLength = CLatmDemux_GetFrameLengthInBits(&hTp->parser.latm);
            hTp->numberOfRawDataBlocks--;
          } else {
            hTp->numberOfRawDataBlocks = 0;
          }
          break;
        default:
          {
            syncLayerFrameBits = 0;
          }
          break;
      }
    }

    headerBits += startPos - (INT)FDKgetValidBits(hBs);
    bitsAvail -= headerBits;

    checkLengthBits  = syncLayerFrameBits;

    /* Check if the whole frame would fit the bitstream buffer */
    if (err == TRANSPORTDEC_OK) {
      if ( (checkLengthBits+headerBits) > ((TRANSPORTDEC_INBUF_SIZE<<3)-7) ) {
        /* We assume that the size of the transport bit buffer has been
           chosen to meet all system requirements, thus this condition
           is considered a synchronisation error. */
        err = TRANSPORTDEC_SYNC_ERROR;
      } else {
        if ( bitsAvail < checkLengthBits ) {
          err = TRANSPORTDEC_NOT_ENOUGH_BITS;
        }
      }
    }

    if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
      break;
    }


    if (err == TRANSPORTDEC_SYNC_ERROR) {
      int bits;

      /* Enforce re-sync of transport headers. */
      hTp->numberOfRawDataBlocks = 0;

      /* Ensure that the bit amount lands and a multiple of TPDEC_SYNCSKIP */
      bits = (bitsAvail + headerBits) % TPDEC_SYNCSKIP;
      /* Rewind - TPDEC_SYNCSKIP, in order to look for a synch one bit ahead next time. */
      FDKpushBiDirectional(hBs, -(headerBits - TPDEC_SYNCSKIP) + bits);
      bitsAvail += headerBits - TPDEC_SYNCSKIP - bits;
      headerBits = 0;      
    }

    /* Frame traversal */
    if ( fTraverseMoreFrames )
    {
      /* Save parser context for early config discovery "rewind all frames" */
      if ( (hTp->flags & TPDEC_EARLY_CONFIG) && !(hTp->flags & TPDEC_MINIMIZE_DELAY))
      {
        /* ignore buffer fullness if just traversing additional frames for ECD */
        ignoreBufferFullness = 1;

        /* Save context in order to return later */
        if ( err == TRANSPORTDEC_OK && startPosFirstFrame == -1 ) {
          startPosFirstFrame = FDKgetValidBits(hBs);
          numRawDataBlocksFirstFrame = hTp->numberOfRawDataBlocks;
          globalFramePosFirstFrame = hTp->globalFramePos;
          rawDataBlockLengthFirstFrame = rawDataBlockLength;
          headerBitsFirstFrame = headerBits;
          errFirstFrame = err;
          FDKmemcpy(contextFirstFrame, &hTp->parser, sizeof(transportdec_parser_t));
        }

        /* Break when config was found or it is not possible anymore to find a config */
        if (startPosFirstFrame != -1 && (fConfigFound || err != TRANSPORTDEC_OK)) {
          break;
        }
      }

      if (err == TRANSPORTDEC_OK) {
        FDKpushFor(hBs, rawDataBlockLength);
        bitsAvail -= rawDataBlockLength;
        numFramesTraversed++;
        /* Ignore error here itentionally. */
        transportDec_AdjustEndOfAccessUnit(hTp);
      }
    }
  } while ( fTraverseMoreFrames || (err == TRANSPORTDEC_SYNC_ERROR && !(hTp->flags & TPDEC_SYNCOK)));

  /* Restore context in case of ECD frame traversal */
  if ( startPosFirstFrame != -1 && (fConfigFound || err != TRANSPORTDEC_OK) ) {
    FDKpushBiDirectional(hBs, FDKgetValidBits(hBs) - startPosFirstFrame);
    FDKmemcpy(&hTp->parser, contextFirstFrame, sizeof(transportdec_parser_t));
    hTp->numberOfRawDataBlocks = numRawDataBlocksFirstFrame;
    hTp->globalFramePos = globalFramePosFirstFrame;
    rawDataBlockLength = rawDataBlockLengthFirstFrame;
    headerBits = headerBitsFirstFrame;
    err = errFirstFrame;
    numFramesTraversed = 0;
  } 

  /* Additional burst data mode buffer fullness check. */
  if ( !(hTp->flags & (TPDEC_IGNORE_BUFFERFULLNESS|TPDEC_SYNCOK)) && err == TRANSPORTDEC_OK) {
    err = additionalHoldOffNeeded(hTp, transportDec_GetBufferFullness(hTp), FDKgetValidBits(hBs) - syncLayerFrameBits);
    if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
      hTp->holdOffFrames++;
    }
  }
  
  /* Rewind for retry because of not enough bits */
  if (err == TRANSPORTDEC_NOT_ENOUGH_BITS) {
    FDKpushBack(hBs, headerBits);
    headerBits = 0;
  }
  else {
    /* reset hold off frame counter */
    hTp->holdOffFrames = 0;
  }

  /* Return to last good frame in case of frame traversal but not ECD. */
  if (numFramesTraversed > 0) {
    FDKpushBack(hBs, rawDataBlockLengthPrevious);
    if (err != TRANSPORTDEC_OK) {
      hTp->numberOfRawDataBlocks = numRawDataBlocksPrevious;
      headerBits = headerBitsPrevious;
    }
    err = TRANSPORTDEC_OK;
  }

bail:
  hTp->auLength[0] = rawDataBlockLength;

  if (err == TRANSPORTDEC_OK) {
    hTp->flags |= TPDEC_SYNCOK;
  }

  if (pHeaderBits != NULL) {
    *pHeaderBits = headerBits;
  }

  if (err == TRANSPORTDEC_SYNC_ERROR) {
    hTp->flags &= ~TPDEC_SYNCOK;
  }

  C_ALLOC_SCRATCH_END(contextFirstFrame, transportdec_parser_t, 1);

  return err;
}
예제 #26
0
파일: psbitdec.cpp 프로젝트: 0x0B501E7E/aac
/*!

  \brief  Reads parametric stereo data from bitstream

  \return

****************************************************************************/
unsigned int
ReadPsData (HANDLE_PS_DEC h_ps_d,          /*!< handle to struct PS_DEC */
            HANDLE_FDK_BITSTREAM hBitBuf,  /*!< handle to struct BIT_BUF */
            int nBitsLeft                  /*!< max number of bits available */
           )
{
  MPEG_PS_BS_DATA *pBsData;

  UCHAR     gr, env;
  SCHAR     dtFlag;
  INT       startbits;
  Huffman   CurrentTable;
  SCHAR     bEnableHeader;

  if (!h_ps_d)
    return 0;

  pBsData = &h_ps_d->bsData[h_ps_d->bsReadSlot].mpeg;

  if (h_ps_d->bsReadSlot != h_ps_d->bsLastSlot) {
    /* Copy last header data */
    FDKmemcpy(pBsData, &h_ps_d->bsData[h_ps_d->bsLastSlot].mpeg, sizeof(MPEG_PS_BS_DATA));
  }


  startbits = (INT) FDKgetValidBits(hBitBuf);

  bEnableHeader = (SCHAR) FDKreadBits (hBitBuf, 1);

  /* Read header */
  if (bEnableHeader) {
    pBsData->bPsHeaderValid = 1;
    pBsData->bEnableIid = (UCHAR) FDKreadBits (hBitBuf, 1);
    if (pBsData->bEnableIid) {
      pBsData->modeIid = (UCHAR) FDKreadBits (hBitBuf, 3);
    }

    pBsData->bEnableIcc = (UCHAR) FDKreadBits (hBitBuf, 1);
    if (pBsData->bEnableIcc) {
      pBsData->modeIcc = (UCHAR) FDKreadBits (hBitBuf, 3);
    }

    pBsData->bEnableExt = (UCHAR) FDKreadBits (hBitBuf, 1);
  }

  pBsData->bFrameClass = (UCHAR) FDKreadBits (hBitBuf, 1);
  if (pBsData->bFrameClass == 0) {
    /* FIX_BORDERS NoEnv=0,1,2,4 */
    pBsData->noEnv = FDK_sbrDecoder_aFixNoEnvDecode[(UCHAR) FDKreadBits (hBitBuf, 2)];
    /* all additional handling of env borders is now in DecodePs() */
  }
  else {
    /* VAR_BORDERS NoEnv=1,2,3,4 */
    pBsData->noEnv = 1+(UCHAR) FDKreadBits (hBitBuf, 2);
    for (env=1; env<pBsData->noEnv+1; env++)
      pBsData->aEnvStartStop[env] = ((UCHAR) FDKreadBits (hBitBuf, 5)) + 1;
    /* all additional handling of env borders is now in DecodePs() */
  }

  /* verify that IID & ICC modes (quant grid, freq res) are supported */
  if ((pBsData->modeIid > 5) || (pBsData->modeIcc > 5)) {
    /* no useful PS data could be read from bitstream */
    h_ps_d->bPsDataAvail[h_ps_d->bsReadSlot] = ppt_none;
    /* discard all remaining bits */
    nBitsLeft -= startbits - FDKgetValidBits(hBitBuf);
    while (nBitsLeft) {
      int i = nBitsLeft;
      if (i>8) {
        i = 8;
      }
      FDKreadBits (hBitBuf, i);
      nBitsLeft -= i;
    }
    return (startbits - FDKgetValidBits(hBitBuf));
  }

  if (pBsData->modeIid > 2){
    pBsData->freqResIid = pBsData->modeIid-3;
    pBsData->bFineIidQ = 1;
  }
  else{
    pBsData->freqResIid = pBsData->modeIid;
    pBsData->bFineIidQ = 0;
  }

  if (pBsData->modeIcc > 2){
    pBsData->freqResIcc = pBsData->modeIcc-3;
  }
  else{
    pBsData->freqResIcc = pBsData->modeIcc;
  }


  /* Extract IID data */
  if (pBsData->bEnableIid) {
    for (env=0; env<pBsData->noEnv; env++) {
      dtFlag = (SCHAR)FDKreadBits (hBitBuf, 1);
      if (!dtFlag)
      {
        if (pBsData->bFineIidQ)
          CurrentTable = (Huffman)&aBookPsIidFineFreqDecode;
        else
          CurrentTable = (Huffman)&aBookPsIidFreqDecode;
      }
      else
      {
        if (pBsData->bFineIidQ)
         CurrentTable = (Huffman)&aBookPsIidFineTimeDecode;
        else
          CurrentTable = (Huffman)&aBookPsIidTimeDecode;
      }

      for (gr = 0; gr < FDK_sbrDecoder_aNoIidBins[pBsData->freqResIid]; gr++)
        pBsData->aaIidIndex[env][gr] = decode_huff_cw(CurrentTable,hBitBuf,NULL);
      pBsData->abIidDtFlag[env] = dtFlag;
    }
  }

  /* Extract ICC data */
  if (pBsData->bEnableIcc) {
    for (env=0; env<pBsData->noEnv; env++) {
      dtFlag = (SCHAR)FDKreadBits (hBitBuf, 1);
      if (!dtFlag)
        CurrentTable = (Huffman)&aBookPsIccFreqDecode;
      else
        CurrentTable = (Huffman)&aBookPsIccTimeDecode;

      for (gr = 0; gr < FDK_sbrDecoder_aNoIccBins[pBsData->freqResIcc]; gr++)
        pBsData->aaIccIndex[env][gr] = decode_huff_cw(CurrentTable,hBitBuf,NULL);
      pBsData->abIccDtFlag[env] = dtFlag;
    }
  }

  if (pBsData->bEnableExt) {

    /*!
    Decoders that support only the baseline version of the PS tool are allowed
    to ignore the IPD/OPD data, but according header data has to be parsed.
    ISO/IEC 14496-3 Subpart 8 Annex 4
    */

    int cnt = FDKreadBits(hBitBuf, PS_EXTENSION_SIZE_BITS);
    if (cnt == (1<<PS_EXTENSION_SIZE_BITS)-1) {
      cnt += FDKreadBits(hBitBuf, PS_EXTENSION_ESC_COUNT_BITS);
    }
    while (cnt--)
      FDKreadBits(hBitBuf, 8);
  }


  /* new PS data was read from bitstream */
  h_ps_d->bPsDataAvail[h_ps_d->bsReadSlot] = ppt_mpeg;



  return (startbits - FDKgetValidBits(hBitBuf));
}
예제 #27
0
/* returns error code */
TRANSPORTDEC_ERROR transportDec_ReadAccessUnit( const HANDLE_TRANSPORTDEC hTp, const UINT layer )
{
  TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
  HANDLE_FDK_BITSTREAM hBs;

  if (!hTp) {
    return TRANSPORTDEC_INVALID_PARAMETER;
  }

  hBs = &hTp->bitStream[layer];

  switch (hTp->transportFmt) {

    case TT_MP4_ADIF:
      /* Read header if not already done */
      if (!(hTp->flags & TPDEC_CONFIG_FOUND))
      {
        CProgramConfig *pce;

        AudioSpecificConfig_Init(&hTp->asc[0]);
        pce = &hTp->asc[0].m_progrConfigElement;
        err = adifRead_DecodeHeader(&hTp->parser.adif, pce, hBs);
        if (err)
          goto bail;

        /* Map adif header to ASC */
        hTp->asc[0].m_aot                    = (AUDIO_OBJECT_TYPE)(pce->Profile + 1);
        hTp->asc[0].m_samplingFrequencyIndex = pce->SamplingFrequencyIndex;
        hTp->asc[0].m_samplingFrequency      = SamplingRateTable[pce->SamplingFrequencyIndex];
        hTp->asc[0].m_channelConfiguration   = 0;
        hTp->asc[0].m_samplesPerFrame        = 1024;
        hTp->avgBitRate                      = hTp->parser.adif.BitRate;

        /* Call callback to decoder. */
        {
          int errC;

          errC = hTp->callbacks.cbUpdateConfig(hTp->callbacks.cbUpdateConfigData, &hTp->asc[0]);
          if (errC == 0) {
            hTp->flags |= TPDEC_CONFIG_FOUND;
          } else {
            err = TRANSPORTDEC_PARSE_ERROR;
            goto bail;
          }
        }
      }
      hTp->auLength[layer] = -1; /* Access Unit data length is unknown. */
      break;

    case TT_MP4_RAW:
      if ((INT)FDKgetValidBits(hBs) <= 0 && layer == 0) {
        err = TRANSPORTDEC_NOT_ENOUGH_BITS;
      }
      /* One Access Unit was filled into buffer.
         So get the length out of the buffer. */
      hTp->auLength[layer] = FDKgetValidBits(hBs);
      hTp->flags |= TPDEC_SYNCOK;
      break;

    case TT_RSVD50:
    case TT_MP4_ADTS:
    case TT_MP4_LOAS:
    case TT_MP4_LATM_MCP0:
    case TT_MP4_LATM_MCP1:
      err = transportDec_readStream(hTp, layer);
      break;

    default:
      err = TRANSPORTDEC_UNSUPPORTED_FORMAT;
      break;
  }

  if (err == TRANSPORTDEC_OK) {
    hTp->accessUnitAnchor[layer] = FDKgetValidBits(hBs);
  } else {
    hTp->accessUnitAnchor[layer] = 0;
  }

bail:
  return err;
}
예제 #28
0
TRANSPORTDEC_ERROR AudioSpecificConfig_Parse(
        CSAudioSpecificConfig *self,
        HANDLE_FDK_BITSTREAM   bs,
        int                    fExplicitBackwardCompatible,
        CSTpCallBacks      *cb
        )
{
  TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK;
  UINT ascStartAnchor = FDKgetValidBits(bs);
  int frameLengthFlag = -1;

  AudioSpecificConfig_Init(self);

  self->m_aot = getAOT(bs);
  self->m_samplingFrequency = getSampleRate(bs, &self->m_samplingFrequencyIndex, 4);
  if (self->m_samplingFrequency <= 0) {
    return TRANSPORTDEC_PARSE_ERROR;
  }

  self->m_channelConfiguration = FDKreadBits(bs,4);

  /* SBR extension ( explicit non-backwards compatible mode ) */
  self->m_sbrPresentFlag = 0;
  self->m_psPresentFlag  = 0;

  if ( self->m_aot == AOT_SBR || self->m_aot == AOT_PS ) {
    self->m_extensionAudioObjectType = AOT_SBR;

    self->m_sbrPresentFlag = 1;
    if ( self->m_aot == AOT_PS ) {
      self->m_psPresentFlag = 1;
    }

    self->m_extensionSamplingFrequency = getSampleRate(bs, &self->m_extensionSamplingFrequencyIndex, 4);
    self->m_aot = getAOT(bs);

  } else {
    self->m_extensionAudioObjectType = AOT_NULL_OBJECT;
  }

  /* Parse whatever specific configs */
  switch (self->m_aot)
  {
#ifdef TP_GA_ENABLE
    case AOT_AAC_LC:
    case AOT_ER_AAC_LC:
    case AOT_ER_AAC_LD:
    case AOT_ER_AAC_SCAL:
    case AOT_ER_BSAC:
      if ((ErrorStatus = GaSpecificConfig_Parse(&self->m_sc.m_gaSpecificConfig, self, bs, ascStartAnchor)) != TRANSPORTDEC_OK ) {
        return (ErrorStatus);
      }
      frameLengthFlag = self->m_sc.m_gaSpecificConfig.m_frameLengthFlag;
      break;
#endif /* TP_GA_ENABLE */
    case AOT_MPEGS:
      if (cb->cbSsc != NULL) {
        cb->cbSsc(
                cb->cbSscData,
                bs,
                self->m_aot,
                self->m_samplingFrequency,
                1,
                0  /* don't know the length */
                );
      } else {
        return TRANSPORTDEC_UNSUPPORTED_FORMAT;
      }
      break;
#ifdef TP_ELD_ENABLE
    case AOT_ER_AAC_ELD:
      if ((ErrorStatus = EldSpecificConfig_Parse(self, bs, cb)) != TRANSPORTDEC_OK ) {
        return (ErrorStatus);
      }
      frameLengthFlag = self->m_sc.m_eldSpecificConfig.m_frameLengthFlag;
      self->m_sbrPresentFlag = self->m_sc.m_eldSpecificConfig.m_sbrPresentFlag;
      self->m_extensionSamplingFrequency = (self->m_sc.m_eldSpecificConfig.m_sbrSamplingRate+1) * self->m_samplingFrequency;
      break;
#endif /* TP_ELD_ENABLE */

    default:
      return TRANSPORTDEC_UNSUPPORTED_FORMAT;
      break;
  }

  /* Frame length */
  switch (self->m_aot)
  {
#if defined(TP_GA_ENABLE) || defined(TP_USAC_ENABLE)
    case AOT_AAC_LC:
    case AOT_ER_AAC_LC:
    case AOT_ER_AAC_SCAL:
    case AOT_ER_BSAC:
    /*case AOT_USAC:*/
      if (!frameLengthFlag)
        self->m_samplesPerFrame = 1024;
      else
        self->m_samplesPerFrame = 960;
      break;
#endif /* TP_GA_ENABLE */
#if defined(TP_GA_ENABLE)
    case AOT_ER_AAC_LD:
      if (!frameLengthFlag)
        self->m_samplesPerFrame = 512;
      else
        self->m_samplesPerFrame = 480;
      break;
#endif /* defined(TP_GA_ENABLE) */
    default:
      break;
  }

  switch (self->m_aot)
  {
    case AOT_ER_AAC_LC:
    case AOT_ER_AAC_LD:
    case AOT_ER_AAC_ELD:
    case AOT_ER_AAC_SCAL:
    case AOT_ER_CELP:
    case AOT_ER_HVXC:
    case AOT_ER_BSAC:
      self->m_epConfig = FDKreadBits(bs,2);

      if (self->m_epConfig > 1) {
        return TRANSPORTDEC_UNSUPPORTED_FORMAT; // EPCONFIG;
      }
      break;
    default:
      break;
  }

  if (fExplicitBackwardCompatible) {
    ErrorStatus = AudioSpecificConfig_ExtensionParse(self, bs, cb);
  }

  return (ErrorStatus);
}
예제 #29
0
static TRANSPORTDEC_ERROR transportDec_readHeader(
        HANDLE_TRANSPORTDEC hTp,
        HANDLE_FDK_BITSTREAM hBs,
        int syncLength,
        int ignoreBufferFullness,
        int *pRawDataBlockLength,
        int *pfTraverseMoreFrames,
        int *pSyncLayerFrameBits,
        int *pfConfigFound,
        int *pHeaderBits
        )
{
  TRANSPORTDEC_ERROR err = TRANSPORTDEC_OK;
  int rawDataBlockLength = *pRawDataBlockLength;
  int fTraverseMoreFrames = (pfTraverseMoreFrames != NULL) ? *pfTraverseMoreFrames : 0;
  int syncLayerFrameBits = (pSyncLayerFrameBits != NULL) ? *pSyncLayerFrameBits : 0;
  int fConfigFound = (pfConfigFound != NULL) ? *pfConfigFound : 0;
  int startPos;

  startPos = FDKgetValidBits(hBs);

  switch (hTp->transportFmt) {
    case TT_MP4_ADTS:
      if (hTp->numberOfRawDataBlocks <= 0)
      {
        int errC;

        hTp->globalFramePos = FDKgetValidBits(hBs);

        /* Parse ADTS header */
        err = adtsRead_DecodeHeader( &hTp->parser.adts, &hTp->asc[0], hBs, ignoreBufferFullness );
        if (err != TRANSPORTDEC_OK) {
          if (err != TRANSPORTDEC_NOT_ENOUGH_BITS) {
            err = TRANSPORTDEC_SYNC_ERROR;
          }
        } else {
          errC = hTp->callbacks.cbUpdateConfig(hTp->callbacks.cbUpdateConfigData, &hTp->asc[0]);
          if (errC != 0) {
            if (errC == TRANSPORTDEC_NEED_TO_RESTART) {
              err = TRANSPORTDEC_NEED_TO_RESTART;
              goto bail;
            } else {
              err = TRANSPORTDEC_SYNC_ERROR;
            }
          } else {
            fConfigFound = 1;
            hTp->numberOfRawDataBlocks = hTp->parser.adts.bs.num_raw_blocks+1;
          }
        }
      }
      else {
        /* Reset CRC because the next bits are the beginning of a raw_data_block() */
        FDKcrcReset(&hTp->parser.adts.crcInfo);
        hTp->parser.adts.bs.num_pce_bits = 0;
      }
      if (err == TRANSPORTDEC_OK) {
        hTp->numberOfRawDataBlocks--;
        rawDataBlockLength = adtsRead_GetRawDataBlockLength(&hTp->parser.adts, (hTp->parser.adts.bs.num_raw_blocks-hTp->numberOfRawDataBlocks));
        if (rawDataBlockLength <= 0) {
          /* No further frame traversal possible. */
          fTraverseMoreFrames = 0;
        }
        syncLayerFrameBits = (hTp->parser.adts.bs.frame_length<<3) - (startPos - FDKgetValidBits(hBs)) - syncLength;
        if (syncLayerFrameBits <= 0) {
          err = TRANSPORTDEC_SYNC_ERROR;
        }
      } else {
        hTp->numberOfRawDataBlocks = 0;
      }
      break;
    case TT_MP4_LOAS:
      if (hTp->numberOfRawDataBlocks <= 0)
      {
        syncLayerFrameBits = FDKreadBits(hBs, 13);
        hTp->parser.latm.m_audioMuxLengthBytes = syncLayerFrameBits;
        syncLayerFrameBits <<= 3;
      }
    case TT_MP4_LATM_MCP1:
    case TT_MP4_LATM_MCP0:
      if (hTp->numberOfRawDataBlocks <= 0)
      {
        hTp->globalFramePos = FDKgetValidBits(hBs);

        err = CLatmDemux_Read(
                hBs,
               &hTp->parser.latm,
                hTp->transportFmt,
               &hTp->callbacks,
                hTp->asc,
               &fConfigFound,
                ignoreBufferFullness);

        if (err != TRANSPORTDEC_OK) {
          if (err != TRANSPORTDEC_NOT_ENOUGH_BITS) {
            err = TRANSPORTDEC_SYNC_ERROR;
          }
        } else {
          hTp->numberOfRawDataBlocks = CLatmDemux_GetNrOfSubFrames(&hTp->parser.latm);
          if (hTp->transportFmt == TT_MP4_LOAS) {
            syncLayerFrameBits -= startPos - FDKgetValidBits(hBs) - (13);            
          }
        }
      } else {
        err = CLatmDemux_ReadPayloadLengthInfo(hBs, &hTp->parser.latm);
        if (err != TRANSPORTDEC_OK) {
          err = TRANSPORTDEC_SYNC_ERROR;
        }
      }
      if (err == TRANSPORTDEC_OK) {
        rawDataBlockLength = CLatmDemux_GetFrameLengthInBits(&hTp->parser.latm);
        hTp->numberOfRawDataBlocks--;
      } else {
        hTp->numberOfRawDataBlocks = 0;
      }
      break;
    default:
      {
        syncLayerFrameBits = 0;
      }
      break;
  }

bail:

  *pRawDataBlockLength = rawDataBlockLength;

  if (pHeaderBits != NULL) {
    *pHeaderBits += startPos - (INT)FDKgetValidBits(hBs);
  }
  if (pfConfigFound != NULL) {
    *pfConfigFound = fConfigFound;
  }

  if (pfTraverseMoreFrames != NULL) {
    *pfTraverseMoreFrames = fTraverseMoreFrames;
  }
  if  (pSyncLayerFrameBits != NULL) {
    *pSyncLayerFrameBits = syncLayerFrameBits;
  }
  if (pfConfigFound != NULL) {
    *pfConfigFound = fConfigFound;
  }

  return err;
}
예제 #30
0
int adtsWrite_EncodeHeader(HANDLE_ADTS hAdts,
                                 HANDLE_FDK_BITSTREAM hBitStream,
                                 int buffer_fullness,
                                 int frame_length)
{
  INT crcIndex = 0;


  hAdts->headerBits = adtsWrite_GetHeaderBits(hAdts);

  FDK_ASSERT(((frame_length+hAdts->headerBits)/8)<0x2000);      /*13 bit*/
  FDK_ASSERT(buffer_fullness<0x800);    /* 11 bit   */

  if (!hAdts->protection_absent) {
    FDKcrcReset(&hAdts->crcInfo);
  }

  if (hAdts->currentBlock == 0) {
    FDKresetBitbuffer(hBitStream, BS_WRITER);
  }

  hAdts->subFrameStartBit = FDKgetValidBits(hBitStream);

  /* Skip new header if this is raw data block 1..n */
  if (hAdts->currentBlock == 0)
  {
    FDKresetBitbuffer(hBitStream, BS_WRITER);

    if (hAdts->num_raw_blocks == 0) {
      crcIndex = adtsWrite_CrcStartReg(hAdts, hBitStream, 0);
    }

    /* fixed header */
    FDKwriteBits(hBitStream, 0xFFF, 12);
    FDKwriteBits(hBitStream, hAdts->mpeg_id, 1);
    FDKwriteBits(hBitStream, hAdts->layer, 2);
    FDKwriteBits(hBitStream, hAdts->protection_absent, 1);
    FDKwriteBits(hBitStream, hAdts->profile, 2);
    FDKwriteBits(hBitStream, hAdts->sample_freq_index, 4);
    FDKwriteBits(hBitStream, hAdts->private_bit, 1);
    FDKwriteBits(hBitStream, getChannelConfig(hAdts->channel_mode), 3);
    FDKwriteBits(hBitStream, hAdts->original, 1);
    FDKwriteBits(hBitStream, hAdts->home, 1);
    /* variable header */
    FDKwriteBits(hBitStream, hAdts->copyright_id, 1);
    FDKwriteBits(hBitStream, hAdts->copyright_start, 1);
    FDKwriteBits(hBitStream, (frame_length + hAdts->headerBits)>>3, 13);
    FDKwriteBits(hBitStream, buffer_fullness, 11);
    FDKwriteBits(hBitStream, hAdts->num_raw_blocks, 2);

    if (!hAdts->protection_absent) {
      int i;

      /* End header CRC portion for single raw data block and write dummy zero values for unknown fields. */
      if (hAdts->num_raw_blocks == 0) {
        adtsWrite_CrcEndReg(hAdts, hBitStream, crcIndex);
      } else {
        for (i=0; i<hAdts->num_raw_blocks; i++) {
          FDKwriteBits(hBitStream, 0, 16);
        }
      }
      FDKwriteBits(hBitStream, 0, 16);
    }
  } /* End of ADTS header */