void dabWrite_CrcEndReg(
                                HANDLE_DAB pDab, /*!< pointer to dab crc info stucture */
                                HANDLE_FDK_BITSTREAM hBs,   /*!< handle to current bit buffer structure */
                                int reg                    /*!< crc region */
                               )
{
    //fprintf(stderr, "dabWrite_CrcEndReg(%p): crc region=%d\n", hBs, reg);
    FDKcrcEndReg(&pDab->crcInfo2, hBs, reg);
}
Example #2
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);
}
Example #3
0
void adtsWrite_CrcEndReg(
                                HANDLE_ADTS pAdts, /*!< pointer to adts crc info stucture */
                                HANDLE_FDK_BITSTREAM hBs,   /*!< handle to current bit buffer structure */
                                int reg                    /*!< crc region */
                               )
{
  if (pAdts->protection_absent == 0)
  {
    FDKcrcEndReg(&pAdts->crcInfo, hBs, reg);
  }
}
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);
}
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);
	}
Example #6
0
TRANSPORTDEC_ERROR adtsRead_DecodeHeader(
        HANDLE_ADTS           pAdts,
        CSAudioSpecificConfig *pAsc,
        HANDLE_FDK_BITSTREAM  hBs,
        const INT             ignoreBufferFullness
        )
{
  INT crcReg;

  INT valBits;
  INT cmp_buffer_fullness;
  int i, adtsHeaderLength;

  STRUCT_ADTS_BS bs;

#ifdef TP_PCE_ENABLE
  CProgramConfig oldPce;
  /* Store the old PCE temporarily. Maybe we'll need it later if we
     have channelConfig=0 and no PCE in this frame. */
  FDKmemcpy(&oldPce, &pAsc->m_progrConfigElement, sizeof(CProgramConfig));
#endif

  valBits = FDKgetValidBits(hBs);

#ifndef ANDROID_DEFAULT_CODE
  if (valBits <= ADTS_HEADERLENGTH) return TRANSPORTDEC_NOT_ENOUGH_BITS;
#endif

  /* adts_fixed_header */
  bs.mpeg_id           = FDKreadBits(hBs, Adts_Length_Id);
  bs.layer             = FDKreadBits(hBs, Adts_Length_Layer);
  bs.protection_absent = FDKreadBits(hBs, Adts_Length_ProtectionAbsent);
  bs.profile           = FDKreadBits(hBs, Adts_Length_Profile);
  bs.sample_freq_index = FDKreadBits(hBs, Adts_Length_SamplingFrequencyIndex);
  bs.private_bit       = FDKreadBits(hBs, Adts_Length_PrivateBit);
  bs.channel_config    = FDKreadBits(hBs, Adts_Length_ChannelConfiguration);
  bs.original          = FDKreadBits(hBs, Adts_Length_OriginalCopy);
  bs.home              = FDKreadBits(hBs, Adts_Length_Home);

  /* adts_variable_header */
  bs.copyright_id    = FDKreadBits(hBs, Adts_Length_CopyrightIdentificationBit);
  bs.copyright_start = FDKreadBits(hBs, Adts_Length_CopyrightIdentificationStart);
  bs.frame_length    = FDKreadBits(hBs, Adts_Length_FrameLength);
  bs.adts_fullness   = FDKreadBits(hBs, Adts_Length_BufferFullness);
  bs.num_raw_blocks  = FDKreadBits(hBs, Adts_Length_NumberOfRawDataBlocksInFrame);
  bs.num_pce_bits    = 0;

  adtsHeaderLength = ADTS_HEADERLENGTH;

  if (!bs.protection_absent) {
    FDKcrcReset(&pAdts->crcInfo);
    FDKpushBack(hBs, 56);   /* complete fixed and variable header! */
    crcReg = FDKcrcStartReg(&pAdts->crcInfo, hBs, 0);
    FDKpushFor(hBs, 56);
  }

  if (! bs.protection_absent && bs.num_raw_blocks>0) {
    for (i=0; i<bs.num_raw_blocks; i++) {
      pAdts->rawDataBlockDist[i] = (USHORT)FDKreadBits(hBs, 16);
      adtsHeaderLength += 16;
    }
    /* Change raw data blocks to delta values */
    pAdts->rawDataBlockDist[bs.num_raw_blocks] = bs.frame_length - 7 - bs.num_raw_blocks*2 - 2 ;
    for (i=bs.num_raw_blocks; i>0; i--) {
      pAdts->rawDataBlockDist[i] -= pAdts->rawDataBlockDist[i-1];
    }
  }

  /* adts_error_check */
  if (!bs.protection_absent)
  {
    USHORT crc_check;

    FDKcrcEndReg(&pAdts->crcInfo, hBs, crcReg);
    crc_check = FDKreadBits(hBs, Adts_Length_CrcCheck);
    adtsHeaderLength += Adts_Length_CrcCheck;

    pAdts->crcReadValue = crc_check;
    /* Check header CRC in case of multiple raw data blocks */
    if (bs.num_raw_blocks > 0) {
      if (pAdts->crcReadValue != FDKcrcGetCRC(&pAdts->crcInfo)) {
        return TRANSPORTDEC_CRC_ERROR;
      }
      /* Reset CRC for the upcoming raw_data_block() */
      FDKcrcReset(&pAdts->crcInfo);
    }
  }


  /* check if valid header */
  if (
      (bs.layer != 0) ||                          // we only support MPEG ADTS
      (bs.sample_freq_index >= 13)                // we only support 96kHz - 7350kHz
      ) {
    FDKpushFor(hBs, bs.frame_length * 8);   // try again one frame later
    return TRANSPORTDEC_UNSUPPORTED_FORMAT;
  }

  /* special treatment of id-bit */
  if ( (bs.mpeg_id == 0) && (pAdts->decoderCanDoMpeg4 == 0) )
  {
    /* MPEG-2 decoder cannot play MPEG-4 bitstreams */


    FDKpushFor(hBs, bs.frame_length * 8);  // try again one frame later
    return TRANSPORTDEC_UNSUPPORTED_FORMAT;
  }

  if (!ignoreBufferFullness)
  {
    cmp_buffer_fullness = bs.frame_length*8 + bs.adts_fullness*32*getNumberOfEffectiveChannels(bs.channel_config);


    /* Evaluate buffer fullness */
    if (bs.adts_fullness != 0x7FF)
    {
      if (pAdts->BufferFullnesStartFlag)
      {
        if ( valBits < cmp_buffer_fullness )
        {
          /* Condition for start of decoding is not fulfilled */

          /* The current frame will not be decoded */
          FDKpushBack(hBs, adtsHeaderLength);

          if ( (cmp_buffer_fullness+adtsHeaderLength) > ((TRANSPORTDEC_INBUF_SIZE<<3)-7) ) {
            return TRANSPORTDEC_SYNC_ERROR;
          } else {
            return TRANSPORTDEC_NOT_ENOUGH_BITS;
          }
        }
        else
        {
          pAdts->BufferFullnesStartFlag = 0;
        }
      }
    }
  }


  /* Get info from ADTS header */
  AudioSpecificConfig_Init(pAsc);
  pAsc->m_aot                    = (AUDIO_OBJECT_TYPE)(bs.profile + 1);
  pAsc->m_samplingFrequencyIndex = bs.sample_freq_index;
  pAsc->m_samplingFrequency      = SamplingRateTable[bs.sample_freq_index];
  pAsc->m_channelConfiguration   = bs.channel_config;
  pAsc->m_samplesPerFrame        = 1024;

#ifdef TP_PCE_ENABLE
  if (bs.channel_config == 0)
  {
    int pceBits = 0;
    UINT alignAnchor = FDKgetValidBits(hBs);
    
    if (FDKreadBits(hBs,3) == ID_PCE) {
      /* Got luck! Parse the PCE */
      int crcReg;
      crcReg = adtsRead_CrcStartReg(pAdts, hBs, 0);

      CProgramConfig_Read(&pAsc->m_progrConfigElement, hBs, alignAnchor);

      adtsRead_CrcEndReg(pAdts, hBs, crcReg);
      pceBits = alignAnchor - FDKgetValidBits(hBs);
      /* store the number of PCE bits */
      bs.num_pce_bits = pceBits;
    }
    else {
      /* No PCE in this frame! Push back the ID tag bits. */
      FDKpushBack(hBs,3);

      /* Encoders do not have to write a PCE in each frame.
         So if we already have a valid PCE we have to use it. */
      if (  oldPce.isValid
        && (bs.sample_freq_index == pAdts->bs.sample_freq_index)  /* we could compare the complete fixed header (bytes) here! */
        && (bs.channel_config    == pAdts->bs.channel_config) /* == 0 */
        && (bs.mpeg_id           == pAdts->bs.mpeg_id) )
      { /* Restore previous PCE which is still valid */
        FDKmemcpy(&pAsc->m_progrConfigElement, &oldPce, sizeof(CProgramConfig));
      }
      else if (bs.mpeg_id == 0) {
        /* If not it seems that we have a implicit channel configuration.
           This mode is not allowed in the context of ISO/IEC 14496-3.
           Skip this frame and try the next one. */
        FDKpushFor(hBs, (bs.frame_length<<3) - adtsHeaderLength - 3);
        return TRANSPORTDEC_UNSUPPORTED_FORMAT;
      }
      /* else {
         ISO/IEC 13818-7 implicit channel mapping is allowed.
         So just open the box of chocolates to see what we got.
      } */
    }
  }
#endif /* TP_PCE_ENABLE */

  /* Copy bit stream data struct to persistent memory now, once we passed all sanity checks above. */
  FDKmemcpy(&pAdts->bs, &bs, sizeof(STRUCT_ADTS_BS));

  return TRANSPORTDEC_OK;
}