Beispiel #1
0
    def _parse_esds(self, esds, fileobj):
        assert esds.name == b"esds"

        ok, data = esds.read(fileobj)
        if not ok:
            raise ValueError("truncated %s atom" % esds.name)

        version, flags, data = _parse_full_atom(data)
        if version != 0:
            # unsupported version, ignore
            return

        try:
            tag, off = cdata.uint8_from(data, 0)
            ES_DescrTag = 0x03
            if tag != ES_DescrTag:
                raise ValueError("unexpected descriptor: %d" % tag)

            base_size, off = _parse_desc_length(data, off)
            es_id, off = cdata.uint16_be_from(data, off)
            es_flags, off = cdata.uint8_from(data, off)
            streamDependenceFlag = cdata.test_bit(es_flags, 7)
            URL_Flag = cdata.test_bit(es_flags, 6)
            OCRstreamFlag = cdata.test_bit(es_flags, 5)
            # streamPriority = es_flags & 0x1f
            if streamDependenceFlag:
                off += 2  # dependsOn_ES_ID
            if URL_Flag:
                url_len, off = cdata.uint8_from(data, off)
                off += url_len  # URLstring
            if OCRstreamFlag:
                off += 2  # OCR_ES_Id
            DecoderConfigDescrTag = 4
            tag, off = cdata.uint8_from(data, off)
            if tag != DecoderConfigDescrTag:
                raise ValueError("unexpected DecoderConfigDescrTag %d" % tag)

            dec_conf_size, off = _parse_desc_length(data, off)
            off += 9  # skip some stuff
            # average bitrate
            self.bitrate, off = cdata.uint32_be_from(data, off)
        except cdata.error as e:
            raise ValueError(e)
Beispiel #2
0
def _parse_desc_length(data, offset):
    """Returns the decoded value and the new offset in data after the value.
    Can raise ValueError in case the value is too long or data too short.
    """

    value = 0
    for i in xrange(4):
        try:
            b, offset = cdata.uint8_from(data, offset)
        except cdata.error as e:
            raise ValueError(e)
        value = (value << 7) | (b & 0x7f)
        if not b >> 7:
            break
    else:
        raise ValueError("invalid descriptor length")

    return value, offset
Beispiel #3
0
    def _parse_alac(self, atom, fileobj):
        # https://alac.macosforge.org/trac/browser/trunk/
        #    ALACMagicCookieDescription.txt

        assert atom.name == b"alac"

        ok, data = atom.read(fileobj)
        if not ok:
            raise ValueError("truncated %s atom" % atom.name)

        version, flags, data = _parse_full_atom(data)
        if version != 0:
            # unsupported version, ignore
            return

        # for some files the AudioSampleEntry values default to 44100/2chan
        # and the real info is in the alac cookie, so prefer it
        try:
            self.channels, off = cdata.uint8_from(data, 9)
            off += 6  # skip some stuff
            self.bitrate, off = cdata.uint32_be_from(data, off)
            self.sample_rate, off = cdata.uint32_be_from(data, off)
        except cdata.error as e:
            raise ValueError(e)