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);
}
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;
}
예제 #3
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);
	}