Example #1
0
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
        }
    }