Skip to content

Commit 1ab3020

Browse files
authored
Merge pull request #291 from AdrianEddy/add-xml-atom
Add support for XML metadata box
2 parents 13efe0b + 7fafe0e commit 1ab3020

File tree

5 files changed

+60
-1
lines changed

5 files changed

+60
-1
lines changed

mp4parse/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ criterion = "0.3"
4242

4343
[features]
4444
3gpp = []
45+
meta-xml = []
4546

4647
[[bench]]
4748
name = "avif_benchmark"

mp4parse/src/boxes.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,10 @@ box_database!(
176176
MetadataItemListEntry 0x696c_7374, // "ilst"
177177
MetadataItemDataEntry 0x6461_7461, // "data"
178178
MetadataItemNameBox 0x6e61_6d65, // "name"
179+
#[cfg(feature = "meta-xml")]
180+
MetadataXMLBox 0x786d_6c20, // "xml "
181+
#[cfg(feature = "meta-xml")]
182+
MetadataBXMLBox 0x6278_6d6c, // "bxml"
179183
UserdataBox 0x7564_7461, // "udta"
180184
AlbumEntry 0xa961_6c62, // "©alb"
181185
ArtistEntry 0xa941_5254, // "©ART"

mp4parse/src/lib.rs

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,19 @@ pub struct MetadataBox {
752752
pub sort_album_artist: Option<TryString>,
753753
/// The name of the composer to sort by 'soco'
754754
pub sort_composer: Option<TryString>,
755+
/// Metadata
756+
#[cfg(feature = "meta-xml")]
757+
pub xml: Option<XmlBox>,
758+
}
759+
760+
/// See ISOBMFF (ISO 14496-12:2015) § 8.11.2.1
761+
#[cfg(feature = "meta-xml")]
762+
#[derive(Debug)]
763+
pub enum XmlBox {
764+
/// XML metadata
765+
StringXmlBox(TryString),
766+
/// Binary XML metadata
767+
BinaryXmlBox(TryVec<u8>),
755768
}
756769

757770
/// Internal data structures.
@@ -763,6 +776,8 @@ pub struct MediaContext {
763776
pub mvex: Option<MovieExtendsBox>,
764777
pub psshs: TryVec<ProtectionSystemSpecificHeaderBox>,
765778
pub userdata: Option<Result<UserdataBox>>,
779+
#[cfg(feature = "meta-xml")]
780+
pub metadata: Option<Result<MetadataBox>>,
766781
}
767782

768783
/// An ISOBMFF item as described by an iloc box. For the sake of avoiding copies,
@@ -2307,6 +2322,12 @@ pub fn read_mp4<T: Read>(f: &mut T) -> Result<MediaContext> {
23072322
BoxType::MovieBox => {
23082323
context = Some(read_moov(&mut b, context)?);
23092324
}
2325+
#[cfg(feature = "meta-xml")]
2326+
BoxType::MetadataBox => {
2327+
if let Some(ctx) = &mut context {
2328+
ctx.metadata = Some(read_meta(&mut b));
2329+
}
2330+
}
23102331
_ => skip_box_content(&mut b)?,
23112332
};
23122333
check_parser_state!(b.content);
@@ -2352,6 +2373,8 @@ fn read_moov<T: Read>(f: &mut BMFFBox<T>, context: Option<MediaContext>) -> Resu
23522373
mut mvex,
23532374
mut psshs,
23542375
mut userdata,
2376+
#[cfg(feature = "meta-xml")]
2377+
metadata,
23552378
} = context.unwrap_or_default();
23562379

23572380
let mut iter = f.box_iter();
@@ -2394,6 +2417,8 @@ fn read_moov<T: Read>(f: &mut BMFFBox<T>, context: Option<MediaContext>) -> Resu
23942417
mvex,
23952418
psshs,
23962419
userdata,
2420+
#[cfg(feature = "meta-xml")]
2421+
metadata,
23972422
})
23982423
}
23992424

@@ -4050,21 +4075,48 @@ fn read_udta<T: Read>(src: &mut BMFFBox<T>) -> Result<UserdataBox> {
40504075
Ok(udta)
40514076
}
40524077

4053-
/// Parse a metadata box inside a udta box
4078+
/// Parse the meta box
4079+
/// See ISOBMFF (ISO 14496-12:2015) § 8.111.
40544080
fn read_meta<T: Read>(src: &mut BMFFBox<T>) -> Result<MetadataBox> {
40554081
let (_, _) = read_fullbox_extra(src)?;
40564082
let mut iter = src.box_iter();
40574083
let mut meta = MetadataBox::default();
40584084
while let Some(mut b) = iter.next_box()? {
40594085
match b.head.name {
40604086
BoxType::MetadataItemListEntry => read_ilst(&mut b, &mut meta)?,
4087+
#[cfg(feature = "meta-xml")]
4088+
BoxType::MetadataXMLBox => read_xml_(&mut b, &mut meta)?,
4089+
#[cfg(feature = "meta-xml")]
4090+
BoxType::MetadataBXMLBox => read_bxml(&mut b, &mut meta)?,
40614091
_ => skip_box_content(&mut b)?,
40624092
};
40634093
check_parser_state!(b.content);
40644094
}
40654095
Ok(meta)
40664096
}
40674097

4098+
/// Parse a XML box inside a meta box
4099+
/// See ISOBMFF (ISO 14496-12:2015) § 8.11.2
4100+
#[cfg(feature = "meta-xml")]
4101+
fn read_xml_<T: Read>(src: &mut BMFFBox<T>, meta: &mut MetadataBox) -> Result<()> {
4102+
if read_fullbox_version_no_flags(src)? != 0 {
4103+
return Err(Error::Unsupported("unsupported XmlBox version"));
4104+
}
4105+
meta.xml = Some(XmlBox::StringXmlBox(src.read_into_try_vec()?));
4106+
Ok(())
4107+
}
4108+
4109+
/// Parse a Binary XML box inside a meta box
4110+
/// See ISOBMFF (ISO 14496-12:2015) § 8.11.2
4111+
#[cfg(feature = "meta-xml")]
4112+
fn read_bxml<T: Read>(src: &mut BMFFBox<T>, meta: &mut MetadataBox) -> Result<()> {
4113+
if read_fullbox_version_no_flags(src)? != 0 {
4114+
return Err(Error::Unsupported("unsupported XmlBox version"));
4115+
}
4116+
meta.xml = Some(XmlBox::BinaryXmlBox(src.read_into_try_vec()?));
4117+
Ok(())
4118+
}
4119+
40684120
/// Parse a metadata box inside a udta box
40694121
fn read_ilst<T: Read>(src: &mut BMFFBox<T>, meta: &mut MetadataBox) -> Result<()> {
40704122
let mut iter = src.box_iter();

mp4parse_capi/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,4 @@ env_logger = "0.8"
3535

3636
[features]
3737
3gpp = ["mp4parse/3gpp"]
38+
meta-xml = ["mp4parse/meta-xml"]

mp4parse_capi/cbindgen.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,4 @@ rename_variants = "QualifiedScreamingSnakeCase"
1818

1919
[defines]
2020
"feature = 3gpp" = "MP4PARSE_FEATURE_3GPP"
21+
"feature = meta-xml" = "MP4PARSE_FEATURE_META_XML"

0 commit comments

Comments
 (0)