/** \fn readStreamMux \brief from vlc */ bool ADM_latm2aac::readAudioMux( uint64_t dts,getBits &bits ) { if( !bits.get(1) ) // use SameStreamMux { if(false==readStreamMuxConfig(bits)) return false; } // streamMuxConfig // if(!numSubFrames) return false; if(conf.audioMuxVersionA==0) { // only 1 subFrames ATM... for(int i=0;i<numSubFrames;i++) { int len=readPayloadInfoLength(bits); if(!len) return false; bool r=readPayload(bits,dts,len); bits.align(); return r; } // otherdata } return true; }
int ParserLatm::parsePayload(unsigned char* data, int len) { cBitStream bs(data, len * 8); bs.SkipBits(24); // skip header if(!bs.GetBit()) { readStreamMuxConfig(&bs); } int tmp; unsigned int slotLen = 0; do { tmp = bs.GetBits(8); slotLen += tmp; } while(tmp == 255); if(slotLen * 8 > (bs.Length() - (unsigned)bs.Index())) { return len; } if(m_curDts == DVD_NOPTS_VALUE) { return len; } // buffer for converted payload data int payloadlength = slotLen + 7; uint8_t* payload = (uint8_t*)malloc(payloadlength); // 7 bytes of ADTS header int offset = 0; putBits(payload, offset, 0xfff, 12); // Sync marker putBits(payload, offset, 0, 1); // ID 0 = MPEG 4 putBits(payload, offset, 0, 2); // Layer putBits(payload, offset, 1, 1); // Protection absent putBits(payload, offset, 2, 2); // AOT putBits(payload, offset, m_sampleRateIndex, 4); putBits(payload, offset, 1, 1); // Private bit putBits(payload, offset, m_channels, 3); putBits(payload, offset, 1, 1); // Original putBits(payload, offset, 1, 1); // Copy putBits(payload, offset, 1, 1); // Copyright identification bit putBits(payload, offset, 1, 1); // Copyright identification start putBits(payload, offset, slotLen, 13); putBits(payload, offset, 0, 11); // Buffer fullness putBits(payload, offset, 0, 2); // RDB in frame // copy AAC data uint8_t* buf = payload + 7; for(unsigned int i = 0; i < slotLen; i++) { *buf++ = bs.GetBits(8); } // send converted payload packet Parser::sendPayload(payload, payloadlength); // free payload buffer free(payload); return len; }