Exemple #1
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 */
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;
}