fn find_descriptor()

in mp4parse/src/lib.rs [4945:5003]


fn find_descriptor(data: &[u8], esds: &mut ES_Descriptor) -> Result<()> {
    // Tags for elementary stream description
    const ESDESCR_TAG: u8 = 0x03;
    const DECODER_CONFIG_TAG: u8 = 0x04;
    const DECODER_SPECIFIC_TAG: u8 = 0x05;

    let mut remains = data;

    // Descriptor length should be more than 2 bytes.
    while remains.len() > 2 {
        let des = &mut Cursor::new(remains);
        let tag = des.read_u8()?;

        // See MPEG-4 Systems (ISO 14496-1:2010) § 8.3.3 for interpreting size of expandable classes

        let mut end: u32 = 0; // It's u8 without declaration type that is incorrect.
                              // MSB of extend_or_len indicates more bytes, up to 4 bytes.
        for _ in 0..4 {
            if des.position() == remains.len().to_u64() {
                // There's nothing more to read, the 0x80 was actually part of
                // the content, and not an extension size.
                end = des.position() as u32;
                break;
            }
            let extend_or_len = des.read_u8()?;
            end = (end << 7) + u32::from(extend_or_len & 0x7F);
            if (extend_or_len & 0b1000_0000) == 0 {
                end += des.position() as u32;
                break;
            }
        }

        if end.to_usize() > remains.len() || u64::from(end) < des.position() {
            return Status::EsdsBadDescriptor.into();
        }

        let descriptor = &remains[des.position().try_into()?..end.to_usize()];

        match tag {
            ESDESCR_TAG => {
                read_es_descriptor(descriptor, esds)?;
            }
            DECODER_CONFIG_TAG => {
                read_dc_descriptor(descriptor, esds)?;
            }
            DECODER_SPECIFIC_TAG => {
                read_ds_descriptor(descriptor, esds)?;
            }
            _ => {
                debug!("Unsupported descriptor, tag {}", tag);
            }
        }

        remains = &remains[end.to_usize()..remains.len()];
        debug!("remains.len(): {}", remains.len());
    }

    Ok(())
}