static status_t parseStreamMuxConfig( ABitReader *bits, unsigned *numSubFrames, unsigned *frameLengthType, ssize_t *fixedFrameLength, bool *otherDataPresent, unsigned *otherDataLenBits) { unsigned audioMuxVersion = bits->getBits(1); unsigned audioMuxVersionA = 0; if (audioMuxVersion == 1) { audioMuxVersionA = bits->getBits(1); } CHECK_EQ(audioMuxVersionA, 0u); // otherwise future spec if (audioMuxVersion != 0) { return ERROR_UNSUPPORTED; // XXX to be implemented; } CHECK_EQ(audioMuxVersion, 0u); // XXX to be implemented unsigned allStreamsSameTimeFraming = bits->getBits(1); CHECK_EQ(allStreamsSameTimeFraming, 1u); // There's only one stream. *numSubFrames = bits->getBits(6); unsigned numProgram = bits->getBits(4); CHECK_EQ(numProgram, 0u); // disabled in RTP LATM unsigned numLayer = bits->getBits(3); CHECK_EQ(numLayer, 0u); // disabled in RTP LATM if (audioMuxVersion == 0) { // AudioSpecificConfig CHECK_EQ(parseAudioSpecificConfig(bits, NULL /* asc */), (status_t)OK); } else { TRESPASS(); // XXX to be implemented } *frameLengthType = bits->getBits(3); *fixedFrameLength = -1; switch (*frameLengthType) { case 0: { /* unsigned bufferFullness = */bits->getBits(8); // The "coreFrameOffset" does not apply since there's only // a single layer. break; } case 1: { *fixedFrameLength = bits->getBits(9); break; } case 2: { return ERROR_UNSUPPORTED; } case 3: case 4: case 5: { /* unsigned CELPframeLengthTableIndex = */bits->getBits(6); break; } case 6: case 7: { /* unsigned HVXCframeLengthTableIndex = */bits->getBits(1); break; } default: break; } *otherDataPresent = bits->getBits(1); *otherDataLenBits = 0; if (*otherDataPresent) { if (audioMuxVersion == 1) { TRESPASS(); // XXX to be implemented } else { *otherDataLenBits = 0; unsigned otherDataLenEsc; do { (*otherDataLenBits) <<= 8; otherDataLenEsc = bits->getBits(1); unsigned otherDataLenTmp = bits->getBits(8); (*otherDataLenBits) += otherDataLenTmp; } while (otherDataLenEsc); } } unsigned crcCheckPresent = bits->getBits(1); if (crcCheckPresent) { /* unsigned crcCheckSum = */bits->getBits(8); } return OK; }
static status_t parseStreamMuxConfig( ABitReader *bits, unsigned *numSubFrames, unsigned *frameLengthType, ssize_t *fixedFrameLength, bool *otherDataPresent, unsigned *otherDataLenBits) { unsigned audioMuxVersion = bits->getBits(1); unsigned audioMuxVersionA = 0; if (audioMuxVersion == 1) { audioMuxVersionA = bits->getBits(1); } CHECK_EQ(audioMuxVersionA, 0u); // otherwise future spec if (audioMuxVersion != 0) { return ERROR_UNSUPPORTED; // XXX to be implemented; } CHECK_EQ(audioMuxVersion, 0u); // XXX to be implemented unsigned allStreamsSameTimeFraming = bits->getBits(1); CHECK_EQ(allStreamsSameTimeFraming, 1u); // There's only one stream. *numSubFrames = bits->getBits(6); unsigned numProgram = bits->getBits(4); CHECK_EQ(numProgram, 0u); // disabled in RTP LATM unsigned numLayer = bits->getBits(3); CHECK_EQ(numLayer, 0u); // disabled in RTP LATM if (audioMuxVersion == 0) { // AudioSpecificConfig CHECK_EQ(parseAudioSpecificConfig(bits, NULL /* asc */), (status_t)OK); } else { TRESPASS(); // XXX to be implemented } *frameLengthType = bits->getBits(3); *fixedFrameLength = -1; switch (*frameLengthType) { case 0: { /* unsigned bufferFullness = */bits->getBits(8); // The "coreFrameOffset" does not apply since there's only // a single layer. break; } case 1: { *fixedFrameLength = bits->getBits(9); break; } case 2: { // reserved TRESPASS(); break; } case 3: case 4: case 5: { /* unsigned CELPframeLengthTableIndex = */bits->getBits(6); break; } case 6: case 7: { /* unsigned HVXCframeLengthTableIndex = */bits->getBits(1); break; } default: break; } #ifdef STE_HARDWARE status_t parseResult = OK; #endif *otherDataPresent = bits->getBits(1); *otherDataLenBits = 0; if (*otherDataPresent) { if (audioMuxVersion == 1) { TRESPASS(); // XXX to be implemented #ifdef STE_HARDWARE } else if (bits->numBitsLeft() < 9) { parseResult = ERROR_MALFORMED; #endif } else { *otherDataLenBits = 0; unsigned otherDataLenEsc; do { (*otherDataLenBits) <<= 8; otherDataLenEsc = bits->getBits(1); unsigned otherDataLenTmp = bits->getBits(8); (*otherDataLenBits) += otherDataLenTmp; #ifdef STE_HARDWARE } while (otherDataLenEsc && bits->numBitsLeft() >= 9); if (otherDataLenEsc) { parseResult = ERROR_MALFORMED; } } } if (parseResult == OK && bits->numBitsLeft() >= 1) { unsigned crcCheckPresent = bits->getBits(1); if (crcCheckPresent && bits->numBitsLeft() >= 8) { /* unsigned crcCheckSum = */bits->getBits(8); } else if (crcCheckPresent && bits->numBitsLeft() < 8) { parseResult = ERROR_MALFORMED; } } else { parseResult = ERROR_MALFORMED; } // Verify that only bits are left for byte aligning and that // any remaining bits are 0 if (bits->numBitsLeft() / 8 > 0) { parseResult = ERROR_MALFORMED; } else { unsigned remainder = bits->getBits(bits->numBitsLeft()); if (remainder != 0) { parseResult = ERROR_MALFORMED; #else } while (otherDataLenEsc); #endif } }