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; }