Bug 1328221 - Support GASpecificConfig audio channel in rust mp4 parser. r=rillian
authorAlfredo.Yang <ayang@mozilla.com>
Wed, 11 Jan 2017 09:03:30 +0800
changeset 376223 d577cf31d3dcb3cb353dba652c2a14d90d2e7882
parent 376222 478ee1543c0d1a4cb834a908336f21c9d3a7203c
child 376224 d22302d250855e2105dc107f63b506363925d1f9
push id1419
push userjlund@mozilla.com
push dateMon, 10 Apr 2017 20:44:07 +0000
treeherdermozilla-release@5e6801b73ef6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrillian
bugs1328221
milestone53.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1328221 - Support GASpecificConfig audio channel in rust mp4 parser. r=rillian MozReview-Commit-ID: IQKxtjatU9J
media/libstagefright/binding/include/mp4parse.h
media/libstagefright/binding/mp4parse-cargo.patch
media/libstagefright/binding/mp4parse/Cargo.toml
media/libstagefright/binding/mp4parse/src/boxes.rs
media/libstagefright/binding/mp4parse/src/lib.rs
media/libstagefright/binding/mp4parse/src/tests.rs
media/libstagefright/binding/mp4parse_capi/Cargo.toml
media/libstagefright/binding/mp4parse_capi/src/lib.rs
third_party/rust/bitreader/.cargo-checksum.json
third_party/rust/bitreader/.travis.yml
third_party/rust/bitreader/Cargo.toml
third_party/rust/bitreader/README.md
third_party/rust/bitreader/src/lib.rs
third_party/rust/bitreader/src/tests.rs
third_party/rust/byteorder/.cargo-checksum.json
third_party/rust/byteorder/.travis.yml
third_party/rust/byteorder/Cargo.toml
third_party/rust/byteorder/Makefile
third_party/rust/byteorder/README.md
third_party/rust/byteorder/session.vim
third_party/rust/byteorder/src/lib.rs
toolkit/library/gtest/rust/Cargo.lock
toolkit/library/rust/Cargo.lock
--- a/media/libstagefright/binding/include/mp4parse.h
+++ b/media/libstagefright/binding/include/mp4parse.h
@@ -93,16 +93,19 @@ typedef struct mp4parse_io {
 } mp4parse_io;
 
 /// Allocate an `mp4parse_parser*` to read from the supplied `mp4parse_io`.
 mp4parse_parser* mp4parse_new(mp4parse_io const* io);
 
 /// Free an `mp4parse_parser*` allocated by `mp4parse_new()`.
 void mp4parse_free(mp4parse_parser* parser);
 
+/// Enable mp4_parser log.
+void mp4parse_log(bool enable);
+
 /// Run the `mp4parse_parser*` allocated by `mp4parse_new()` until EOF or error.
 mp4parse_error mp4parse_read(mp4parse_parser* parser);
 
 /// Return the number of tracks parsed by previous `mp4parse_read()` call.
 mp4parse_error mp4parse_get_track_count(mp4parse_parser const* parser, uint32_t* count);
 
 /// Fill the supplied `mp4parse_track_info` with metadata for `track`.
 mp4parse_error mp4parse_get_track_info(mp4parse_parser* parser, uint32_t track_index, mp4parse_track_info* info);
--- a/media/libstagefright/binding/mp4parse-cargo.patch
+++ b/media/libstagefright/binding/mp4parse-cargo.patch
@@ -1,23 +1,23 @@
 diff --git a/media/libstagefright/binding/mp4parse/Cargo.toml b/media/libstagefright/binding/mp4parse/Cargo.toml
 index ff9422c..814c4c6 100644
 --- a/media/libstagefright/binding/mp4parse/Cargo.toml
 +++ b/media/libstagefright/binding/mp4parse/Cargo.toml
 @@ -18,18 +18,12 @@ exclude = [
  ]
  
  [dependencies]
--byteorder = "0.5.0"
+-byteorder = "1.0.0"
 -afl = { version = "0.1.1", optional = true }
 -afl-plugin = { version = "0.1.1", optional = true }
 -abort_on_panic = { version = "1.0.0", optional = true }
--bitreader = { version = "0.1.0" }
-+byteorder = "0.5.0"
-+bitreader = { version = "0.1.0" }
+-bitreader = { version = "0.2.0" }
++byteorder = "1.0.0"
++bitreader = { version = "0.2.0" }
 
  [dev-dependencies]
  test-assembler = "0.1.2"
  
 -[features]
 -fuzz = ["afl", "afl-plugin", "abort_on_panic"]
 -
  # Somewhat heavy-handed, but we want at least -Z force-overflow-checks=on.
@@ -29,17 +29,17 @@ index aeeebc65..5c0836a 100644
 +++ b/media/libstagefright/binding/mp4parse_capi/Cargo.toml
 @@ -18,18 +18,10 @@ exclude = [
    "*.mp4",
  ]
  
 -build = "build.rs"
 -
  [dependencies]
- byteorder = "0.5.0"
+ byteorder = "1.0.0"
  "mp4parse" = {version = "0.6.0", path = "../mp4parse"}
  
 -[build-dependencies]
 -rusty-cheddar = "0.3.2"
 -
 -[features]
 -fuzz = ["mp4parse/fuzz"]
 -
--- a/media/libstagefright/binding/mp4parse/Cargo.toml
+++ b/media/libstagefright/binding/mp4parse/Cargo.toml
@@ -14,17 +14,17 @@ license = "MPL-2.0"
 repository = "https://github.com/mozilla/mp4parse-rust"
 
 # Avoid complaints about trying to package test files.
 exclude = [
   "*.mp4",
 ]
 
 [dependencies]
-byteorder = "0.5.0"
-bitreader = { version = "0.1.0" }
+byteorder = "1.0.0"
+bitreader = { version = "0.2.0" }
 
 [dev-dependencies]
 test-assembler = "0.1.2"
 
 # Somewhat heavy-handed, but we want at least -Z force-overflow-checks=on.
 [profile.release]
 debug-assertions = true
--- a/media/libstagefright/binding/mp4parse/src/boxes.rs
+++ b/media/libstagefright/binding/mp4parse/src/boxes.rs
@@ -1,29 +1,99 @@
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
+use std::fmt;
 
 macro_rules! box_database {
     ($($boxenum:ident $boxtype:expr),*,) => {
-        #[derive(Debug, Clone, Copy, PartialEq)]
+        #[derive(Clone, Copy, PartialEq)]
         pub enum BoxType {
             $($boxenum),*,
             UnknownBox(u32),
         }
 
         impl From<u32> for BoxType {
             fn from(t: u32) -> BoxType {
                 use self::BoxType::*;
                 match t {
                     $($boxtype => $boxenum),*,
                     _ => UnknownBox(t),
                 }
             }
         }
+
+        impl Into<u32> for BoxType {
+            fn into(self) -> u32 {
+                use self::BoxType::*;
+                match self {
+                    $($boxenum => $boxtype),*,
+                    UnknownBox(t) => t,
+                }
+            }
+        }
+
+        impl fmt::Debug for BoxType {
+            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+                let fourcc: FourCC = From::from(self.clone());
+                write!(f, "{}", fourcc)
+            }
+        }
+    }
+}
+
+#[derive(Default, PartialEq)]
+pub struct FourCC {
+    pub value: String
+}
+
+impl From<u32> for FourCC {
+    fn from(number: u32) -> FourCC {
+        let mut box_chars = Vec::new();
+        for x in 0..4 {
+            let c = (number >> x * 8 & 0x000000FF) as u8;
+            box_chars.push(c);
+        }
+        box_chars.reverse();
+
+        let box_string = match String::from_utf8(box_chars) {
+            Ok(t) => t,
+            _ => String::from("null"), // error to retrieve fourcc
+        };
+
+        FourCC {
+            value: box_string
+        }
+    }
+}
+
+impl From<BoxType> for FourCC {
+    fn from(t: BoxType) -> FourCC {
+        let box_num: u32 = Into::into(t);
+        From::from(box_num)
+    }
+}
+
+impl<'a> From<&'a str> for FourCC {
+    fn from(v: &'a str) -> FourCC {
+        FourCC {
+            value: v.to_owned()
+        }
+    }
+}
+
+impl fmt::Debug for FourCC {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "{}", self.value)
+    }
+}
+
+impl fmt::Display for FourCC {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "{}", self.value)
     }
 }
 
 box_database!(
     FileTypeBox                       0x66747970, // "ftyp"
     MovieBox                          0x6d6f6f76, // "moov"
     MovieHeaderBox                    0x6d766864, // "mvhd"
     TrackBox                          0x7472616b, // "trak"
--- a/media/libstagefright/binding/mp4parse/src/lib.rs
+++ b/media/libstagefright/binding/mp4parse/src/lib.rs
@@ -12,17 +12,17 @@ extern crate byteorder;
 extern crate bitreader;
 use byteorder::{ReadBytesExt, WriteBytesExt};
 use bitreader::{BitReader, ReadInto};
 use std::io::{Read, Take};
 use std::io::Cursor;
 use std::cmp;
 
 mod boxes;
-use boxes::BoxType;
+use boxes::{BoxType, FourCC};
 
 // Unit tests.
 #[cfg(test)]
 mod tests;
 
 // Arbitrary buffer size limit used for raw read_bufs on a box.
 const BUF_SIZE_LIMIT: u64 = 1024 * 1024;
 
@@ -101,19 +101,19 @@ struct BoxHeader {
     size: u64,
     /// Offset to the start of the contained data (or header size).
     offset: u64,
 }
 
 /// File type box 'ftyp'.
 #[derive(Debug)]
 struct FileTypeBox {
-    major_brand: u32,
+    major_brand: FourCC,
     minor_version: u32,
-    compatible_brands: Vec<u32>,
+    compatible_brands: Vec<FourCC>,
 }
 
 /// Movie header box 'mvhd'.
 #[derive(Debug)]
 struct MovieHeaderBox {
     pub timescale: u32,
     duration: u64,
 }
@@ -191,17 +191,17 @@ struct TimeToSampleBox {
 struct Sample {
     sample_count: u32,
     sample_delta: u32,
 }
 
 // Handler reference box 'hdlr'
 #[derive(Debug)]
 struct HandlerBox {
-    handler_type: u32,
+    handler_type: FourCC,
 }
 
 // Sample description box 'stsd'
 #[derive(Debug)]
 struct SampleDescriptionBox {
     descriptions: Vec<SampleEntry>,
 }
 
@@ -471,16 +471,25 @@ impl<'a, T: Read> BMFFBox<'a, T> {
         &self.head
     }
 
     fn box_iter<'b>(&'b mut self) -> BoxIter<BMFFBox<'a, T>> {
         BoxIter::new(self)
     }
 }
 
+impl<'a, T: Read> Drop for BMFFBox<'a, T> {
+    fn drop(&mut self) {
+        if self.content.limit() > 0 {
+            let name: FourCC = From::from(self.head.name);
+            log!("Dropping {} bytes in '{}'", self.content.limit(), name);
+        }
+    }
+}
+
 /// Read and parse a box header.
 ///
 /// Call this first to determine the type of a particular mp4 box
 /// and its length. Used internally for dispatching to specific
 /// parsers for the internal content, or to get the length to
 /// skip unknown or uninteresting boxes.
 fn read_box_header<T: ReadBytesExt>(src: &mut T) -> Result<BoxHeader> {
     let size32 = be_u32(src)?;
@@ -788,19 +797,20 @@ fn read_mdia<T: Read>(f: &mut BMFFBox<T>
             BoxType::MediaHeaderBox => {
                 let (mdhd, duration, timescale) = parse_mdhd(&mut b, track)?;
                 track.duration = duration;
                 track.timescale = timescale;
                 log!("{:?}", mdhd);
             }
             BoxType::HandlerBox => {
                 let hdlr = read_hdlr(&mut b)?;
-                match hdlr.handler_type {
-                    0x76696465 /* 'vide' */ => track.track_type = TrackType::Video,
-                    0x736f756e /* 'soun' */ => track.track_type = TrackType::Audio,
+
+                match hdlr.handler_type.value.as_ref() {
+                    "vide" => track.track_type = TrackType::Video,
+                    "soun" => track.track_type = TrackType::Audio,
                     _ => (),
                 }
                 log!("{:?}", hdlr);
             }
             BoxType::MediaInformationBox => read_minf(&mut b, track)?,
             _ => skip_box_content(&mut b)?,
         };
         check_parser_state!(b.content);
@@ -869,20 +879,20 @@ fn read_ftyp<T: Read>(src: &mut BMFFBox<
     let bytes_left = src.bytes_left();
     if bytes_left % 4 != 0 {
         return Err(Error::InvalidData("invalid ftyp size"));
     }
     // Is a brand_count of zero valid?
     let brand_count = bytes_left / 4;
     let mut brands = Vec::new();
     for _ in 0..brand_count {
-        brands.push(be_u32(src)?);
+        brands.push(From::from(be_u32(src)?));
     }
     Ok(FileTypeBox {
-        major_brand: major,
+        major_brand: From::from(major),
         minor_version: minor,
         compatible_brands: brands,
     })
 }
 
 /// Parse an mvhd box.
 fn read_mvhd<T: Read>(src: &mut BMFFBox<T>) -> Result<MovieHeaderBox> {
     let (version, _) = read_fullbox_extra(src)?;
@@ -1271,25 +1281,80 @@ fn read_ds_descriptor(data: &[u8], esds:
         0x0F => {
             Some(ReadInto::read(bit_reader, 24)?)
         },
         _ => {
             frequency_table.iter().find(|item| item.0 == sample_index).map(|x| x.1)
         },
     };
 
-    let channel_counts: u16 = ReadInto::read(bit_reader, 4)?;
+    let mut channel_counts: u16 = ReadInto::read(bit_reader, 4)?;
+
+    // parsing GASpecificConfig
+    bit_reader.skip(1)?;        // frameLengthFlag
+    let depend_on_core_order: u8 = ReadInto::read(bit_reader, 1)?;
+    if depend_on_core_order > 0 {
+        bit_reader.skip(14)?;   // codeCoderDelay
+    }
+    bit_reader.skip(1)?;        // extensionFlag
+
+    // When channel_counts is 0, we need to parse the program_config_element
+    // to calculate the channel counts.
+    if channel_counts == 0 {
+        log!("Parsing program_config_element for channel counts");
+
+        bit_reader.skip(4)?;    // element_instance_tag
+        bit_reader.skip(2)?;    // object_type
+        bit_reader.skip(4)?;    // sampling_frequency_index
+        let num_front_channel: u8 = ReadInto::read(bit_reader, 4)?;
+        let num_side_channel: u8 = ReadInto::read(bit_reader, 4)?;
+        let num_back_channel:u8 = ReadInto::read(bit_reader, 4)?;
+        let num_lfe_channel: u8 = ReadInto::read(bit_reader, 2)?;
+        bit_reader.skip(3)?;    // num_assoc_data
+        bit_reader.skip(4)?;    // num_valid_cc
+
+        let mono_mixdown_present: bool = ReadInto::read(bit_reader, 1)?;
+        if mono_mixdown_present {
+            bit_reader.skip(4)?;    // mono_mixdown_element_number
+        }
+
+        let stereo_mixdown_present: bool = ReadInto::read(bit_reader, 1)?;
+        if stereo_mixdown_present {
+            bit_reader.skip(4)?;    // stereo_mixdown_element_number
+        }
+
+        let matrix_mixdown_idx_present: bool = ReadInto::read(bit_reader, 1)?;
+        if matrix_mixdown_idx_present {
+            bit_reader.skip(2)?;    // matrix_mixdown_idx
+            bit_reader.skip(1)?;    // pseudo_surround_enable
+        }
+
+        channel_counts += read_surround_channel_count(bit_reader, num_front_channel)?;
+        channel_counts += read_surround_channel_count(bit_reader, num_side_channel)?;
+        channel_counts += read_surround_channel_count(bit_reader, num_back_channel)?;
+        channel_counts += read_surround_channel_count(bit_reader, num_lfe_channel)?;
+    }
 
     esds.audio_object_type = Some(audio_object_type);
     esds.audio_sample_rate = sample_frequency;
     esds.audio_channel_count = Some(channel_counts);
 
     Ok(())
 }
 
+fn read_surround_channel_count(bit_reader: &mut BitReader, channels: u8) -> Result<u16> {
+    let mut count = 0;
+    for _ in 0..channels {
+        let is_cpe: bool = ReadInto::read(bit_reader, 1)?;
+        count += if is_cpe { 2 } else { 1 };
+        bit_reader.skip(4)?;
+    }
+    Ok(count)
+}
+
 fn read_dc_descriptor(data: &[u8], esds: &mut ES_Descriptor) -> Result<()> {
     let des = &mut Cursor::new(data);
     let object_profile = des.read_u8()?;
 
     // Skip uninteresting fields.
     skip(des, 12)?;
 
     if data.len() > des.position() as usize {
@@ -1465,17 +1530,17 @@ pub fn serialize_opus_header<W: byteorde
 
 /// Parse a hdlr box.
 fn read_hdlr<T: Read>(src: &mut BMFFBox<T>) -> Result<HandlerBox> {
     let (_, _) = read_fullbox_extra(src)?;
 
     // Skip uninteresting fields.
     skip(src, 4)?;
 
-    let handler_type = be_u32(src)?;
+    let handler_type = FourCC::from(be_u32(src)?);
 
     // Skip uninteresting fields.
     skip(src, 12)?;
 
     let bytes_left = src.bytes_left();
     let _name = read_null_terminated_string(src, bytes_left)?;
 
     Ok(HandlerBox {
--- a/media/libstagefright/binding/mp4parse/src/tests.rs
+++ b/media/libstagefright/binding/mp4parse/src/tests.rs
@@ -7,17 +7,17 @@
 
 use std::io::Cursor;
 use super::read_mp4;
 use super::MediaContext;
 use super::Error;
 extern crate test_assembler;
 use self::test_assembler::*;
 
-use boxes::BoxType;
+use boxes::{BoxType, FourCC};
 
 enum BoxSize {
     Short(u32),
     Long(u64),
     UncheckedShort(u32),
     UncheckedLong(u64),
     Auto,
 }
@@ -125,21 +125,21 @@ fn read_ftyp() {
          .append_bytes(b"isom")
          .append_bytes(b"mp42")
     });
     let mut iter = super::BoxIter::new(&mut stream);
     let mut stream = iter.next_box().unwrap().unwrap();
     assert_eq!(stream.head.name, BoxType::FileTypeBox);
     assert_eq!(stream.head.size, 24);
     let parsed = super::read_ftyp(&mut stream).unwrap();
-    assert_eq!(parsed.major_brand, 0x6d703432); // mp42
+    assert_eq!(parsed.major_brand, FourCC::from("mp42")); // mp42
     assert_eq!(parsed.minor_version, 0);
     assert_eq!(parsed.compatible_brands.len(), 2);
-    assert_eq!(parsed.compatible_brands[0], 0x69736f6d); // isom
-    assert_eq!(parsed.compatible_brands[1], 0x6d703432); // mp42
+    assert_eq!(parsed.compatible_brands[0], FourCC::from("isom")); // isom
+    assert_eq!(parsed.compatible_brands[1], FourCC::from("mp42")); // mp42
 }
 
 #[test]
 fn read_truncated_ftyp() {
     // We declare a 24 byte box, but only write 20 bytes.
     let mut stream = make_box(BoxSize::UncheckedShort(24), b"ftyp", |s| {
         s.append_bytes(b"mp42")
             .B32(0) // minor version
@@ -167,21 +167,21 @@ fn read_ftyp_case() {
          .append_bytes(b"ISOM")
          .append_bytes(b"MP42")
     });
     let mut iter = super::BoxIter::new(&mut stream);
     let mut stream = iter.next_box().unwrap().unwrap();
     assert_eq!(stream.head.name, BoxType::FileTypeBox);
     assert_eq!(stream.head.size, 24);
     let parsed = super::read_ftyp(&mut stream).unwrap();
-    assert_eq!(parsed.major_brand, 0x4d503432);
+    assert_eq!(parsed.major_brand, FourCC::from("MP42"));
     assert_eq!(parsed.minor_version, 0);
     assert_eq!(parsed.compatible_brands.len(), 2);
-    assert_eq!(parsed.compatible_brands[0], 0x49534f4d); // ISOM
-    assert_eq!(parsed.compatible_brands[1], 0x4d503432); // MP42
+    assert_eq!(parsed.compatible_brands[0], FourCC::from("ISOM")); // ISOM
+    assert_eq!(parsed.compatible_brands[1], FourCC::from("MP42")); // MP42
 }
 
 #[test]
 fn read_elst_v0() {
     let mut stream = make_fullbox(BoxSize::Short(28), b"elst", 0, |s| {
         s.B32(1) // list count
           // first entry
          .B32(1234) // duration
@@ -399,17 +399,17 @@ fn read_hdlr() {
          .append_bytes(b"VideoHandler")
          .B8(0) // null-terminate string
     });
     let mut iter = super::BoxIter::new(&mut stream);
     let mut stream = iter.next_box().unwrap().unwrap();
     assert_eq!(stream.head.name, BoxType::HandlerBox);
     assert_eq!(stream.head.size, 45);
     let parsed = super::read_hdlr(&mut stream).unwrap();
-    assert_eq!(parsed.handler_type, 0x76696465); // vide
+    assert_eq!(parsed.handler_type, FourCC::from("vide"));
 }
 
 #[test]
 fn read_hdlr_short_name() {
     let mut stream = make_fullbox(BoxSize::Short(33), b"hdlr", 0, |s| {
         s.B32(0)
          .append_bytes(b"vide")
          .B32(0)
@@ -417,34 +417,34 @@ fn read_hdlr_short_name() {
          .B32(0)
          .B8(0) // null-terminate string
     });
     let mut iter = super::BoxIter::new(&mut stream);
     let mut stream = iter.next_box().unwrap().unwrap();
     assert_eq!(stream.head.name, BoxType::HandlerBox);
     assert_eq!(stream.head.size, 33);
     let parsed = super::read_hdlr(&mut stream).unwrap();
-    assert_eq!(parsed.handler_type, 0x76696465); // vide
+    assert_eq!(parsed.handler_type, FourCC::from("vide"));
 }
 
 #[test]
 fn read_hdlr_zero_length_name() {
     let mut stream = make_fullbox(BoxSize::Short(32), b"hdlr", 0, |s| {
         s.B32(0)
          .append_bytes(b"vide")
          .B32(0)
          .B32(0)
          .B32(0)
     });
     let mut iter = super::BoxIter::new(&mut stream);
     let mut stream = iter.next_box().unwrap().unwrap();
     assert_eq!(stream.head.name, BoxType::HandlerBox);
     assert_eq!(stream.head.size, 32);
     let parsed = super::read_hdlr(&mut stream).unwrap();
-    assert_eq!(parsed.handler_type, 0x76696465); // vide
+    assert_eq!(parsed.handler_type, FourCC::from("vide"));
 }
 
 fn flac_streaminfo() -> Vec<u8> {
     vec![
         0x10, 0x00, 0x10, 0x00, 0x00, 0x0a, 0x11, 0x00,
         0x38, 0x32, 0x0a, 0xc4, 0x42, 0xf0, 0x00, 0xc9,
         0xdf, 0xae, 0xb5, 0x66, 0xfc, 0x02, 0x15, 0xa3,
         0xb1, 0x54, 0x61, 0x47, 0x0f, 0xfb, 0x05, 0x00,
@@ -853,8 +853,34 @@ fn read_qt_wave_atom() {
 
     let mut iter = super::BoxIter::new(&mut stream);
     let mut stream = iter.next_box().unwrap().unwrap();
     let mut track = super::Track::new(0);
     super::read_audio_sample_entry(&mut stream, &mut track)
           .expect("fail to read qt wave atom");
     assert_eq!(track.codec_type, super::CodecType::MP3);
 }
+
+#[test]
+fn read_esds() {
+    let aac_esds =
+        vec![
+            0x03, 0x24, 0x00, 0x00, 0x00, 0x04, 0x1c, 0x40,
+            0x15, 0x00, 0x12, 0x00, 0x00, 0x01, 0xf4, 0x00,
+            0x00, 0x01, 0xf4, 0x00, 0x05, 0x0d, 0x13, 0x00,
+            0x05, 0x88, 0x05, 0x00, 0x48, 0x21, 0x10, 0x00,
+            0x56, 0xe5, 0x98, 0x06, 0x01, 0x02,
+        ];
+    let mut stream = make_box(BoxSize::Auto, b"esds", |s| {
+        s.B32(0) // reserved
+         .append_bytes(aac_esds.as_slice())
+    });
+    let mut iter = super::BoxIter::new(&mut stream);
+    let mut stream = iter.next_box().unwrap().unwrap();
+
+    let es = super::read_esds(&mut stream).unwrap();
+
+    assert_eq!(es.audio_codec, super::CodecType::AAC);
+    assert_eq!(es.audio_object_type, Some(2));
+    assert_eq!(es.audio_sample_rate, Some(24000));
+    assert_eq!(es.audio_channel_count, Some(6));
+    assert_eq!(es.codec_esds, aac_esds);
+}
--- a/media/libstagefright/binding/mp4parse_capi/Cargo.toml
+++ b/media/libstagefright/binding/mp4parse_capi/Cargo.toml
@@ -14,14 +14,14 @@ license = "MPL-2.0"
 repository = "https://github.com/mozilla/mp4parse-rust"
 
 # Avoid complaints about trying to package test files.
 exclude = [
   "*.mp4",
 ]
 
 [dependencies]
-byteorder = "0.5.0"
+byteorder = "1.0.0"
 "mp4parse" = {version = "0.6.0", path = "../mp4parse"}
 
 # Somewhat heavy-handed, but we want at least -Z force-overflow-checks=on.
 [profile.release]
 debug-assertions = true
--- a/media/libstagefright/binding/mp4parse_capi/src/lib.rs
+++ b/media/libstagefright/binding/mp4parse_capi/src/lib.rs
@@ -262,26 +262,33 @@ pub unsafe extern fn mp4parse_new(io: *c
     }
     let parser = Box::new(mp4parse_parser(Wrap {
         context: MediaContext::new(),
         io: (*io).clone(),
         poisoned: false,
         opus_header: HashMap::new(),
         pssh_data: Vec::new(),
     }));
+
     Box::into_raw(parser)
 }
 
 /// Free an `mp4parse_parser*` allocated by `mp4parse_new()`.
 #[no_mangle]
 pub unsafe extern fn mp4parse_free(parser: *mut mp4parse_parser) {
     assert!(!parser.is_null());
     let _ = Box::from_raw(parser);
 }
 
+/// Enable mp4_parser log.
+#[no_mangle]
+pub unsafe extern fn mp4parse_log(enable: bool) {
+    mp4parse::set_debug_mode(enable);
+}
+
 /// Run the `mp4parse_parser*` allocated by `mp4parse_new()` until EOF or error.
 #[no_mangle]
 pub unsafe extern fn mp4parse_read(parser: *mut mp4parse_parser) -> mp4parse_error {
     // Validate arguments from C.
     if parser.is_null() || (*parser).poisoned() {
         return MP4PARSE_ERROR_BADARG;
     }
 
--- a/third_party/rust/bitreader/.cargo-checksum.json
+++ b/third_party/rust/bitreader/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"f9b1ca6ae27d1c18215265024629a8960c31379f206d9ed20f64e0b2dcf79805","Cargo.toml":"958f2305ab8afcf59f3eeef619f95e511ee2721654417784bbec5ef135fe608b","LICENSE":"cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30","README.md":"dc19fd728ea91808d5f4109b9343f6a6bfb931f20a3094f4d5d77f9343b09579","src/lib.rs":"343e09a0e40a7d88e69e346bcc0816260e91abafbc9fe854b3aae16305cb717e","src/tests.rs":"bf0d60d6b70f79eb36a394ba51eae7c36e185778f31ef9bfba12399ec60b6e75"},"package":"b245039eddbd1a051b8bfa5d5b6afaad6d34d172057a15d561e80b50b4978e8d"}
\ No newline at end of file
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"f9b1ca6ae27d1c18215265024629a8960c31379f206d9ed20f64e0b2dcf79805",".travis.yml":"f79c29325421aef57d8191a6a19450b62a431a78a6a5be39f5e8ec259316cdac","Cargo.toml":"672e17bc43e09796c9af69270ab47db16b77da461176ca8692ac211f6b7c09f5","LICENSE":"cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30","README.md":"979a08488d27db4ea70e4db255ea759d7f4c4c0b65b53e32bd3743117538d20b","src/lib.rs":"62b815c44f50074bc199b6abe9ef2728c3e5dad9539ebe9107b3d818c32c453f","src/tests.rs":"e90f5e1ccbc4c41c42cb3ad0f88aee26b1e08e953b7979a4ddbe0a0826ddbad4"},"package":"8319aa6588c40cce19a135009ec70dc730a34ed9d27bab2409298b948546da7a"}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/third_party/rust/bitreader/.travis.yml
@@ -0,0 +1,4 @@
+language: rust
+rust:
+  - stable
+  - nightly
--- a/third_party/rust/bitreader/Cargo.toml
+++ b/third_party/rust/bitreader/Cargo.toml
@@ -1,18 +1,19 @@
 [package]
 name = "bitreader"
-version = "0.1.0"
+version = "0.2.0"
 authors = ["Ilkka Rauta <ilkka.rauta@gmail.com>"]
 
 description = """
 BitReader helps reading individual bits from a slice of bytes.
 
 You can read "unusual" numbers of bits from the byte slice, for example 13 bits
 at once. The reader internally keeps track of position within the buffer.
 """
 
+documentation = "https://docs.rs/bitreader"
 homepage = "https://github.com/irauta/bitreader"
 repository = "https://github.com/irauta/bitreader"
 
 keywords = ["bit", "bits", "bitstream"]
 
 license = "Apache-2.0"
--- a/third_party/rust/bitreader/README.md
+++ b/third_party/rust/bitreader/README.md
@@ -1,19 +1,23 @@
 # BitReader
 
 BitReader is a helper type to extract strings of bits from a slice of bytes.
 
+[![Published Package](https://img.shields.io/crates/v/bitreader.svg)](https://crates.io/crates/bitreader)
+[![Documentation](https://docs.rs/bitreader/badge.svg)](https://docs.rs/bitreader)
+[![Build Status](https://travis-ci.org/irauta/bitreader.svg)](https://travis-ci.org/irauta/bitreader)
+
 Here is how you read first a single bit, then three bits and finally four bits from a byte buffer:
 
     use bitreader::BitReader;
 
     let slice_of_u8 = &[0b1000_1111];
     let mut reader = BitReader::new(slice_of_u8);
 
     // You obviously should use try! or some other error handling mechanism here
     let a_single_bit = reader.read_u8(1).unwrap(); // 1
     let more_bits = reader.read_u8(3).unwrap(); // 0
     let last_bits_of_byte = reader.read_u8(4).unwrap(); // 0b1111
 
 You can naturally read bits from longer buffer of data than just a single byte.
 
-As you read bits, the internal cursor of BitReader moves on along the stream of bits. Little endian format is assumed when reading the multi-byte values. BitReader supports reading maximum of 64 bits at a time (with read_u64). Reading signed values directly is not supported at the moment.
+As you read bits, the internal cursor of BitReader moves on along the stream of bits. Little endian format is assumed when reading the multi-byte values. BitReader supports reading maximum of 64 bits at a time (with read_u64).
--- a/third_party/rust/bitreader/src/lib.rs
+++ b/third_party/rust/bitreader/src/lib.rs
@@ -156,16 +156,25 @@ impl<'a> BitReader<'a> {
 
     /// Read at most 64 bits into a i64.
     /// Assumes the bits are stored in two's complement format.
     pub fn read_i64(&mut self, bit_count: u8) -> Result<i64> {
         let value = try!(self.read_signed_value(bit_count, 64));
         Ok(value)
     }
 
+    /// Read a single bit as a boolean value.
+    /// Interprets 1 as true and 0 as false.
+    pub fn read_bool(&mut self) -> Result<bool> {
+        match try!(self.read_value(1, 1)) {
+            0 => Ok(false),
+            _ => Ok(true),
+        }
+    }
+
     /// Skip arbitrary number of bits. However, you can skip at most to the end of the byte slice.
     pub fn skip(&mut self, bit_count: u64) -> Result<()> {
         let end_position = self.position + bit_count;
         if end_position > self.bytes.len() as u64 * 8 {
             return Err(BitReaderError::NotEnoughData {
                 position: self.position,
                 length: (self.bytes.len() * 8) as u64,
                 requested: bit_count,
@@ -278,34 +287,38 @@ impl fmt::Display for BitReaderError {
         }
     }
 }
 
 /// Helper trait to allow reading bits into a variable without explicitly mentioning its type.
 ///
 /// If you can't or want, for some reason, to use BitReader's read methods (`read_u8` etc.) but
 /// want to rely on type inference instead, you can use the ReadInto trait. The trait is
-/// implemented for all basic integer types (8/16/32/64 bits, signed/unsigned).
+/// implemented for all basic integer types (8/16/32/64 bits, signed/unsigned)
+/// and the boolean type.
 ///
 /// ```
 /// use bitreader::{BitReader,ReadInto};
 ///
-/// let slice_of_u8 = &[0b1100_0000];
+/// let slice_of_u8 = &[0b1110_0000];
 /// let mut reader = BitReader::new(slice_of_u8);
 ///
 /// struct Foo {
-///     bar: u8
+///     bar: u8,
+///     valid: bool,
 /// }
 ///
 /// // No type mentioned here, instead the type of bits is inferred from the type of Foo::bar,
 /// // and consequently the correct "overload" is used.
 /// let bits = ReadInto::read(&mut reader, 2).unwrap();
+/// let valid = ReadInto::read(&mut reader, 1).unwrap();
 ///
-/// let foo = Foo { bar: bits };
-/// assert_eq!(foo.bar, 3)
+/// let foo = Foo { bar: bits, valid: valid };
+/// assert_eq!(foo.bar, 3);
+/// assert!(foo.valid);
 /// ```
 pub trait ReadInto
     where Self: Sized
 {
     fn read(reader: &mut BitReader, bits: u8) -> Result<Self>;
 }
 
 // There's eight almost identical implementations, let's make this easier.
@@ -323,8 +336,18 @@ impl_read_into!(u8, read_u8);
 impl_read_into!(u16, read_u16);
 impl_read_into!(u32, read_u32);
 impl_read_into!(u64, read_u64);
 
 impl_read_into!(i8, read_i8);
 impl_read_into!(i16, read_i16);
 impl_read_into!(i32, read_i32);
 impl_read_into!(i64, read_i64);
+
+// We can't cast to bool, so this requires a separate method.
+impl ReadInto for bool {
+    fn read(reader: &mut BitReader, bits: u8) -> Result<Self> {
+        match try!(reader.read_u8(bits)) {
+            0 => Ok(false),
+            _ => Ok(true),
+        }
+    }
+}
--- a/third_party/rust/bitreader/src/tests.rs
+++ b/third_party/rust/bitreader/src/tests.rs
@@ -36,17 +36,17 @@ fn read_buffer() {
     assert_eq!(reader.read_u8(3).unwrap(), 0b100);
 
     assert!(reader.is_aligned(1));
 
     assert_eq!(reader.read_u32(32).unwrap(), 0b1001_1001_1001_1001_1001_1001_1001_1001);
 
     assert_eq!(reader.read_u8(4).unwrap(), 0b1110);
     assert_eq!(reader.read_u8(3).unwrap(), 0b011);
-    assert_eq!(reader.read_u8(1).unwrap(), 0b1);
+    assert_eq!(reader.read_bool().unwrap(), true);
 
     // Could also be 8 at this point!
     assert!(reader.is_aligned(4));
 }
 
 #[test]
 fn try_all_sizes() {
     let bytes = &[
@@ -78,28 +78,32 @@ fn try_all_sizes() {
     for byte in bytes {
         assert_eq!(reader.read_u8(8).unwrap(), *byte);
     }
 }
 
 #[test]
 fn skipping_and_zero_reads() {
     let bytes = &[
-        0b1011_0101, 0b1110_1010, 0b1010_1100,
+        0b1011_0101, 0b1110_1010, 0b1010_1100, 0b0011_0101,
     ];
 
     let mut reader = BitReader::new(bytes);
 
     assert_eq!(reader.read_u8(4).unwrap(), 0b1011);
     // Reading zero bits should be a no-op
     assert_eq!(reader.read_u8(0).unwrap(), 0b0);
     assert_eq!(reader.read_u8(4).unwrap(), 0b0101);
     reader.skip(3).unwrap(); // 0b111
     assert_eq!(reader.read_u16(10).unwrap(), 0b0101010101);
     assert_eq!(reader.read_u8(3).unwrap(), 0b100);
+    reader.skip(4).unwrap(); // 0b0011
+    assert_eq!(reader.read_u32(2).unwrap(), 0b01);
+    assert_eq!(reader.read_bool().unwrap(), false);
+    assert_eq!(reader.read_bool().unwrap(), true);
 }
 
 #[test]
 fn errors() {
     let bytes = &[
         0b1011_0101, 0b1110_1010, 0b1010_1100,
     ];
 
@@ -133,8 +137,22 @@ fn signed_values() {
             (x >> 8) as u8,
             x as u8,
         ];
         let mut reader = BitReader::new(bytes);
         assert_eq!(reader.read_u8(4).unwrap(), if x < 0 { 0b1111 } else { 0 });
         assert_eq!(reader.read_i16(12).unwrap(), x);
     }
 }
+
+#[test]
+fn boolean_values() {
+    let bytes: Vec<u8> = (0..16).collect();
+    let mut reader = BitReader::new(&bytes);
+    for v in &bytes {
+        assert_eq!(reader.read_bool().unwrap(), false);
+        reader.skip(3).unwrap();
+        assert_eq!(reader.read_bool().unwrap(), v & 0x08 == 8);
+        assert_eq!(reader.read_bool().unwrap(), v & 0x04 == 4);
+        assert_eq!(reader.read_bool().unwrap(), v & 0x02 == 2);
+        assert_eq!(reader.read_bool().unwrap(), v & 0x01 == 1);
+    }
+}
--- a/third_party/rust/byteorder/.cargo-checksum.json
+++ b/third_party/rust/byteorder/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"2879af3c0512f976015d532e2d768f04ff22fdcf8745b69b955b78fda321c3fb",".travis.yml":"81545ce3c6c72111a68434464c3f9fa8df9cbe39759a081fac527628ab21ae0c","COPYING":"01c266bced4a434da0051174d6bee16a4c82cf634e2679b6155d40d75012390f","Cargo.toml":"a7282931b50dff2e463f82baaed95a9d76636bc0fef3e921acd8ca69eab32b83","LICENSE-MIT":"0f96a83840e146e43c0ec96a22ec1f392e0680e6c1226e6f3ba87e0740af850f","Makefile":"a45a128685a2ae7d4fa39d310786674417ee113055ef290a11f88002285865fc","README.md":"fbcc46b6d0a585096737f50922818b59016b69d959b05f1b29863b2af8e4da43","UNLICENSE":"7e12e5df4bae12cb21581ba157ced20e1986a0508dd10d0e8a4ab9a4cf94e85c","benches/bench.rs":"f583692d829c8dfe19b1d5b9e968ccf5c74d6733367ca183edff74041a6afedd","session.vim":"95cb1d7caf0ff7fbe76ec911988d908ddd883381c925ba64b537695bc9f021c4","src/lib.rs":"ef9e7a218fa3a4912c47f6840d32b975940d98277b6c9be85e8d7d045552eb87","src/new.rs":"161c21b7ebb5668c7cc70b46b0eb37709e06bb9c854f2fdfc6ce3d3babcbf3de"},"package":"0fc10e8cc6b2580fda3f36eb6dc5316657f812a3df879a44a66fc9f0fdbc4855"}
\ No newline at end of file
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"2879af3c0512f976015d532e2d768f04ff22fdcf8745b69b955b78fda321c3fb",".travis.yml":"c8243fb884ca390f5a7b8cc45e1c0d5bbbdd7e4e82ada2dc1880b3a904c9ce12","COPYING":"01c266bced4a434da0051174d6bee16a4c82cf634e2679b6155d40d75012390f","Cargo.toml":"b6cd79e1f2a93cd8a5c6e6dd7985c46fc26e442ae5b8ed4a0ff37a4ad4708023","LICENSE-MIT":"0f96a83840e146e43c0ec96a22ec1f392e0680e6c1226e6f3ba87e0740af850f","README.md":"0559514b9d7488e96fb7a2f3c043a62fadf3495a1e10602d109ce79ee67da998","UNLICENSE":"7e12e5df4bae12cb21581ba157ced20e1986a0508dd10d0e8a4ab9a4cf94e85c","benches/bench.rs":"f583692d829c8dfe19b1d5b9e968ccf5c74d6733367ca183edff74041a6afedd","src/lib.rs":"b038b8a84b2b7b2143b2835185b3cbbacaf056fa8a2f03bec84bfd79c913c726","src/new.rs":"161c21b7ebb5668c7cc70b46b0eb37709e06bb9c854f2fdfc6ce3d3babcbf3de"},"package":"c40977b0ee6b9885c9013cd41d9feffdd22deb3bb4dc3a71d901cc7a77de18c8"}
\ No newline at end of file
--- a/third_party/rust/byteorder/.travis.yml
+++ b/third_party/rust/byteorder/.travis.yml
@@ -1,15 +1,15 @@
 language: rust
-matrix:
-  include:
-    - rust: "nightly"
-      env: TEST_SUITE=suite_nightly
-    - rust: "beta"
-      env: TEST_SUITE=suite_beta
-    - rust: "stable"
-      env: TEST_SUITE=suite_stable
+rust:
+  - 1.12.0
+  - stable
+  - beta
+  - nightly
 script:
   - cargo build --verbose
+  - cargo doc
   - cargo test --verbose
-  - if [ "$TEST_SUITE" = "suite_nightly" ]; then
+  - cargo test --verbose --no-default-features --lib
+  - if [ "$TRAVIS_RUST_VERSION" = "nightly" ]; then
       cargo bench --verbose;
+      cargo bench --verbose --no-default-features;
     fi
--- a/third_party/rust/byteorder/Cargo.toml
+++ b/third_party/rust/byteorder/Cargo.toml
@@ -1,25 +1,26 @@
 [package]
 name = "byteorder"
-version = "0.5.3"  #:version
+version = "1.0.0"  #:version
 authors = ["Andrew Gallant <jamslam@gmail.com>"]
 description = "Library for reading/writing numbers in big-endian and little-endian."
-documentation = "http://burntsushi.net/rustdoc/byteorder/"
+documentation = "https://docs.rs/byteorder"
 homepage = "https://github.com/BurntSushi/byteorder"
 repository = "https://github.com/BurntSushi/byteorder"
 readme = "README.md"
 keywords = ["byte", "endian", "big-endian", "little-endian", "binary"]
 license = "Unlicense/MIT"
 
 [lib]
 name = "byteorder"
+bench = false
 
 [dev-dependencies]
-quickcheck = "0.2"
+quickcheck = "0.4"
 rand = "0.3"
 
 [features]
 default = ["std"]
 std = []
 
 [profile.bench]
 opt-level = 3
deleted file mode 100644
--- a/third_party/rust/byteorder/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-all:
-	echo Nothing to do...
-
-ctags:
-	ctags --recurse --options=ctags.rust --languages=Rust
-
-docs:
-	cargo doc
-	in-dir ./target/doc fix-perms
-	rscp ./target/doc/* gopher:~/www/burntsushi.net/rustdoc/
-
-push:
-	git push origin master
-	git push github master
--- a/third_party/rust/byteorder/README.md
+++ b/third_party/rust/byteorder/README.md
@@ -1,34 +1,31 @@
 This crate provides convenience methods for encoding and decoding numbers in
-either big-endian or little-endian order. This is meant to replace the old
-methods defined on the standard library `Reader` and `Writer` traits.
+either big-endian or little-endian order.
 
 [![Build status](https://api.travis-ci.org/BurntSushi/byteorder.png)](https://travis-ci.org/BurntSushi/byteorder)
 [![](http://meritbadge.herokuapp.com/byteorder)](https://crates.io/crates/byteorder)
 
 Dual-licensed under MIT or the [UNLICENSE](http://unlicense.org).
 
 
 ### Documentation
 
-[http://burntsushi.net/rustdoc/byteorder/](http://burntsushi.net/rustdoc/byteorder/).
-
-The documentation includes examples.
+https://docs.rs/byteorder
 
 
 ### Installation
 
 This crate works with Cargo and is on
-[crates.io](https://crates.io/crates/byteorder). The package is regularly
-updated.  Add it to your `Cargo.toml` like so:
+[crates.io](https://crates.io/crates/byteorder). Add it to your `Cargo.toml`
+like so:
 
 ```toml
 [dependencies]
-byteorder = "0.5"
+byteorder = "1"
 ```
 
 If you want to augment existing `Read` and `Write` traits, then import the
 extension methods like so:
 
 ```rust
 extern crate byteorder;
 
@@ -50,10 +47,10 @@ assert_eq!(768, rdr.read_u16::<BigEndian
 
 ### `no_std` crates
 
 This crate has a feature, `std`, that is enabled by default. To use this crate
 in a `no_std` context, add the following to your `Cargo.toml`:
 
 ```toml
 [dependencies]
-byteorder = { version = "0.5", default-features = false }
+byteorder = { version = "1", default-features = false }
 ```
deleted file mode 100644
--- a/third_party/rust/byteorder/session.vim
+++ /dev/null
@@ -1,1 +0,0 @@
-au BufWritePost *.rs silent!make ctags > /dev/null 2>&1
--- a/third_party/rust/byteorder/src/lib.rs
+++ b/third_party/rust/byteorder/src/lib.rs
@@ -31,26 +31,24 @@ use byteorder::{LittleEndian, WriteBytes
 
 let mut wtr = vec![];
 wtr.write_u16::<LittleEndian>(517).unwrap();
 wtr.write_u16::<LittleEndian>(768).unwrap();
 assert_eq!(wtr, vec![5, 2, 0, 3]);
 ```
 */
 
-#![crate_name = "byteorder"]
-#![doc(html_root_url = "http://burntsushi.net/rustdoc/byteorder")]
-
+#![deny(missing_docs)]
 #![cfg_attr(not(feature = "std"), no_std)]
 
-#![deny(missing_docs)]
-
 #[cfg(feature = "std")]
 extern crate core;
 
+use core::fmt::Debug;
+use core::hash::Hash;
 use core::mem::transmute;
 use core::ptr::copy_nonoverlapping;
 
 #[cfg(feature = "std")]
 pub use new::{ReadBytesExt, WriteBytesExt};
 
 #[cfg(feature = "std")]
 mod new;
@@ -113,17 +111,18 @@ fn pack_size(n: u64) -> usize {
 ///
 /// ```rust
 /// use byteorder::{ByteOrder, BigEndian};
 ///
 /// let mut buf = [0; 2];
 /// BigEndian::write_i16(&mut buf, -50_000);
 /// assert_eq!(-50_000, BigEndian::read_i16(&buf));
 /// ```
-pub trait ByteOrder {
+pub trait ByteOrder
+    : Clone + Copy + Debug + Default + Eq + Hash + Ord + PartialEq + PartialOrd {
     /// Reads an unsigned 16 bit integer from `buf`.
     ///
     /// Panics when `buf.len() < 2`.
     fn read_u16(buf: &[u8]) -> u16;
 
     /// Reads an unsigned 32 bit integer from `buf`.
     ///
     /// Panics when `buf.len() < 4`.
@@ -259,23 +258,37 @@ pub trait ByteOrder {
         Self::write_u64(buf, unsafe { transmute(n) })
     }
 }
 
 /// Defines big-endian serialization.
 ///
 /// Note that this type has no value constructor. It is used purely at the
 /// type level.
-#[allow(missing_copy_implementations)] pub enum BigEndian {}
+#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
+pub enum BigEndian {}
+
+impl Default for BigEndian {
+    fn default() -> BigEndian {
+        unreachable!()
+    }
+}
 
 /// Defines little-endian serialization.
 ///
 /// Note that this type has no value constructor. It is used purely at the
 /// type level.
-#[allow(missing_copy_implementations)] pub enum LittleEndian {}
+#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
+pub enum LittleEndian {}
+
+impl Default for LittleEndian {
+    fn default() -> LittleEndian {
+        unreachable!()
+    }
+}
 
 /// Defines network byte order serialization.
 ///
 /// Network byte order is defined by [RFC 1700][1] to be big-endian, and is
 /// referred to in several protocol specifications.  This type is an alias of
 /// BigEndian.
 ///
 /// [1]: https://tools.ietf.org/html/rfc1700
@@ -434,23 +447,23 @@ impl ByteOrder for LittleEndian {
     }
 }
 
 #[cfg(test)]
 mod test {
     extern crate quickcheck;
     extern crate rand;
 
-    use test::rand::thread_rng;
-    use test::quickcheck::{QuickCheck, StdGen, Testable};
+    use self::rand::thread_rng;
+    use self::quickcheck::{QuickCheck, StdGen, Testable};
 
-    const U64_MAX: u64 = ::std::u64::MAX;
-    const I64_MAX: u64 = ::std::i64::MAX as u64;
+    pub const U64_MAX: u64 = ::core::u64::MAX;
+    pub const I64_MAX: u64 = ::core::i64::MAX as u64;
 
-    fn qc_sized<A: Testable>(f: A, size: u64) {
+    pub fn qc_sized<A: Testable>(f: A, size: u64) {
         QuickCheck::new()
             .gen(StdGen::new(thread_rng(), size as usize))
             .tests(1_00)
             .max_tests(10_000)
             .quickcheck(f);
     }
 
     macro_rules! qc_byte_order {
@@ -492,17 +505,17 @@ mod test {
                     }
                     qc_sized(prop as fn($ty_int) -> bool, max);
                 }
             }
         );
         ($name:ident, $ty_int:ident, $max:expr,
          $read:ident, $write:ident) => (
             mod $name {
-                use std::mem::size_of;
+                use core::mem::size_of;
                 use {BigEndian, ByteOrder, NativeEndian, LittleEndian};
                 use super::qc_sized;
 
                 #[test]
                 fn big_endian() {
                     fn prop(n: $ty_int) -> bool {
                         let bytes = size_of::<$ty_int>();
                         let mut buf = [0; 8];
@@ -532,24 +545,24 @@ mod test {
                         n == NativeEndian::$read(&mut buf[..bytes])
                     }
                     qc_sized(prop as fn($ty_int) -> bool, $max - 1);
                 }
             }
         );
     }
 
-    qc_byte_order!(prop_u16, u16, ::std::u16::MAX as u64, read_u16, write_u16);
-    qc_byte_order!(prop_i16, i16, ::std::i16::MAX as u64, read_i16, write_i16);
-    qc_byte_order!(prop_u32, u32, ::std::u32::MAX as u64, read_u32, write_u32);
-    qc_byte_order!(prop_i32, i32, ::std::i32::MAX as u64, read_i32, write_i32);
-    qc_byte_order!(prop_u64, u64, ::std::u64::MAX as u64, read_u64, write_u64);
-    qc_byte_order!(prop_i64, i64, ::std::i64::MAX as u64, read_i64, write_i64);
-    qc_byte_order!(prop_f32, f32, ::std::u64::MAX as u64, read_f32, write_f32);
-    qc_byte_order!(prop_f64, f64, ::std::i64::MAX as u64, read_f64, write_f64);
+    qc_byte_order!(prop_u16, u16, ::core::u16::MAX as u64, read_u16, write_u16);
+    qc_byte_order!(prop_i16, i16, ::core::i16::MAX as u64, read_i16, write_i16);
+    qc_byte_order!(prop_u32, u32, ::core::u32::MAX as u64, read_u32, write_u32);
+    qc_byte_order!(prop_i32, i32, ::core::i32::MAX as u64, read_i32, write_i32);
+    qc_byte_order!(prop_u64, u64, ::core::u64::MAX as u64, read_u64, write_u64);
+    qc_byte_order!(prop_i64, i64, ::core::i64::MAX as u64, read_i64, write_i64);
+    qc_byte_order!(prop_f32, f32, ::core::u64::MAX as u64, read_f32, write_f32);
+    qc_byte_order!(prop_f64, f64, ::core::i64::MAX as u64, read_f64, write_f64);
 
     qc_byte_order!(prop_uint_1, u64, super::U64_MAX, 1, read_uint, write_uint);
     qc_byte_order!(prop_uint_2, u64, super::U64_MAX, 2, read_uint, write_uint);
     qc_byte_order!(prop_uint_3, u64, super::U64_MAX, 3, read_uint, write_uint);
     qc_byte_order!(prop_uint_4, u64, super::U64_MAX, 4, read_uint, write_uint);
     qc_byte_order!(prop_uint_5, u64, super::U64_MAX, 5, read_uint, write_uint);
     qc_byte_order!(prop_uint_6, u64, super::U64_MAX, 6, read_uint, write_uint);
     qc_byte_order!(prop_uint_7, u64, super::U64_MAX, 7, read_uint, write_uint);
@@ -559,138 +572,16 @@ mod test {
     qc_byte_order!(prop_int_2, i64, super::I64_MAX, 2, read_int, write_int);
     qc_byte_order!(prop_int_3, i64, super::I64_MAX, 3, read_int, write_int);
     qc_byte_order!(prop_int_4, i64, super::I64_MAX, 4, read_int, write_int);
     qc_byte_order!(prop_int_5, i64, super::I64_MAX, 5, read_int, write_int);
     qc_byte_order!(prop_int_6, i64, super::I64_MAX, 6, read_int, write_int);
     qc_byte_order!(prop_int_7, i64, super::I64_MAX, 7, read_int, write_int);
     qc_byte_order!(prop_int_8, i64, super::I64_MAX, 8, read_int, write_int);
 
-    macro_rules! qc_bytes_ext {
-        ($name:ident, $ty_int:ident, $max:expr,
-         $bytes:expr, $read:ident, $write:ident) => (
-            mod $name {
-                use std::io::Cursor;
-                use {
-                    ReadBytesExt, WriteBytesExt,
-                    BigEndian, NativeEndian, LittleEndian,
-                };
-                use super::qc_sized;
-
-                #[test]
-                fn big_endian() {
-                    let max = ($max - 1) >> (8 * (8 - $bytes));
-                    fn prop(n: $ty_int) -> bool {
-                        let mut wtr = vec![];
-                        wtr.$write::<BigEndian>(n).unwrap();
-                        let mut rdr = Vec::new();
-                        rdr.extend(wtr[8 - $bytes..].iter().map(|&x|x));
-                        let mut rdr = Cursor::new(rdr);
-                        n == rdr.$read::<BigEndian>($bytes).unwrap()
-                    }
-                    qc_sized(prop as fn($ty_int) -> bool, max);
-                }
-
-                #[test]
-                fn little_endian() {
-                    let max = ($max - 1) >> (8 * (8 - $bytes));
-                    fn prop(n: $ty_int) -> bool {
-                        let mut wtr = vec![];
-                        wtr.$write::<LittleEndian>(n).unwrap();
-                        let mut rdr = Cursor::new(wtr);
-                        n == rdr.$read::<LittleEndian>($bytes).unwrap()
-                    }
-                    qc_sized(prop as fn($ty_int) -> bool, max);
-                }
-
-                #[test]
-                fn native_endian() {
-                    let max = ($max - 1) >> (8 * (8 - $bytes));
-                    fn prop(n: $ty_int) -> bool {
-                        let mut wtr = vec![];
-                        wtr.$write::<NativeEndian>(n).unwrap();
-                        let mut rdr = Cursor::new(wtr);
-                        n == rdr.$read::<NativeEndian>($bytes).unwrap()
-                    }
-                    qc_sized(prop as fn($ty_int) -> bool, max);
-                }
-            }
-        );
-        ($name:ident, $ty_int:ident, $max:expr, $read:ident, $write:ident) => (
-            mod $name {
-                use std::io::Cursor;
-                use {
-                    ReadBytesExt, WriteBytesExt,
-                    BigEndian, NativeEndian, LittleEndian,
-                };
-                use super::qc_sized;
-
-                #[test]
-                fn big_endian() {
-                    fn prop(n: $ty_int) -> bool {
-                        let mut wtr = vec![];
-                        wtr.$write::<BigEndian>(n).unwrap();
-                        let mut rdr = Cursor::new(wtr);
-                        n == rdr.$read::<BigEndian>().unwrap()
-                    }
-                    qc_sized(prop as fn($ty_int) -> bool, $max - 1);
-                }
-
-                #[test]
-                fn little_endian() {
-                    fn prop(n: $ty_int) -> bool {
-                        let mut wtr = vec![];
-                        wtr.$write::<LittleEndian>(n).unwrap();
-                        let mut rdr = Cursor::new(wtr);
-                        n == rdr.$read::<LittleEndian>().unwrap()
-                    }
-                    qc_sized(prop as fn($ty_int) -> bool, $max - 1);
-                }
-
-                #[test]
-                fn native_endian() {
-                    fn prop(n: $ty_int) -> bool {
-                        let mut wtr = vec![];
-                        wtr.$write::<NativeEndian>(n).unwrap();
-                        let mut rdr = Cursor::new(wtr);
-                        n == rdr.$read::<NativeEndian>().unwrap()
-                    }
-                    qc_sized(prop as fn($ty_int) -> bool, $max - 1);
-                }
-            }
-        );
-    }
-
-    qc_bytes_ext!(prop_ext_u16, u16, ::std::u16::MAX as u64, read_u16, write_u16);
-    qc_bytes_ext!(prop_ext_i16, i16, ::std::i16::MAX as u64, read_i16, write_i16);
-    qc_bytes_ext!(prop_ext_u32, u32, ::std::u32::MAX as u64, read_u32, write_u32);
-    qc_bytes_ext!(prop_ext_i32, i32, ::std::i32::MAX as u64, read_i32, write_i32);
-    qc_bytes_ext!(prop_ext_u64, u64, ::std::u64::MAX as u64, read_u64, write_u64);
-    qc_bytes_ext!(prop_ext_i64, i64, ::std::i64::MAX as u64, read_i64, write_i64);
-    qc_bytes_ext!(prop_ext_f32, f32, ::std::u64::MAX as u64, read_f32, write_f32);
-    qc_bytes_ext!(prop_ext_f64, f64, ::std::i64::MAX as u64, read_f64, write_f64);
-
-    qc_bytes_ext!(prop_ext_uint_1, u64, super::U64_MAX, 1, read_uint, write_u64);
-    qc_bytes_ext!(prop_ext_uint_2, u64, super::U64_MAX, 2, read_uint, write_u64);
-    qc_bytes_ext!(prop_ext_uint_3, u64, super::U64_MAX, 3, read_uint, write_u64);
-    qc_bytes_ext!(prop_ext_uint_4, u64, super::U64_MAX, 4, read_uint, write_u64);
-    qc_bytes_ext!(prop_ext_uint_5, u64, super::U64_MAX, 5, read_uint, write_u64);
-    qc_bytes_ext!(prop_ext_uint_6, u64, super::U64_MAX, 6, read_uint, write_u64);
-    qc_bytes_ext!(prop_ext_uint_7, u64, super::U64_MAX, 7, read_uint, write_u64);
-    qc_bytes_ext!(prop_ext_uint_8, u64, super::U64_MAX, 8, read_uint, write_u64);
-
-    qc_bytes_ext!(prop_ext_int_1, i64, super::I64_MAX, 1, read_int, write_i64);
-    qc_bytes_ext!(prop_ext_int_2, i64, super::I64_MAX, 2, read_int, write_i64);
-    qc_bytes_ext!(prop_ext_int_3, i64, super::I64_MAX, 3, read_int, write_i64);
-    qc_bytes_ext!(prop_ext_int_4, i64, super::I64_MAX, 4, read_int, write_i64);
-    qc_bytes_ext!(prop_ext_int_5, i64, super::I64_MAX, 5, read_int, write_i64);
-    qc_bytes_ext!(prop_ext_int_6, i64, super::I64_MAX, 6, read_int, write_i64);
-    qc_bytes_ext!(prop_ext_int_7, i64, super::I64_MAX, 7, read_int, write_i64);
-    qc_bytes_ext!(prop_ext_int_8, i64, super::I64_MAX, 8, read_int, write_i64);
-
     // Test that all of the byte conversion functions panic when given a
     // buffer that is too small.
     //
     // These tests are critical to ensure safety, otherwise we might end up
     // with a buffer overflow.
     macro_rules! too_small {
         ($name:ident, $maximally_small:expr, $zero:expr,
          $read:ident, $write:ident) => (
@@ -795,8 +686,135 @@ mod test {
 
     #[test]
     fn uint_bigger_buffer() {
         use {ByteOrder, LittleEndian};
         let n = LittleEndian::read_uint(&[1, 2, 3, 4, 5, 6, 7, 8], 5);
         assert_eq!(n, 0x0504030201);
     }
 }
+
+#[cfg(test)]
+#[cfg(feature = "std")]
+mod stdtests {
+    macro_rules! qc_bytes_ext {
+        ($name:ident, $ty_int:ident, $max:expr,
+         $bytes:expr, $read:ident, $write:ident) => (
+            mod $name {
+                use std::io::Cursor;
+                use {
+                    ReadBytesExt, WriteBytesExt,
+                    BigEndian, NativeEndian, LittleEndian,
+                };
+                use test::qc_sized;
+
+                #[test]
+                fn big_endian() {
+                    let max = ($max - 1) >> (8 * (8 - $bytes));
+                    fn prop(n: $ty_int) -> bool {
+                        let mut wtr = vec![];
+                        wtr.$write::<BigEndian>(n).unwrap();
+                        let mut rdr = Vec::new();
+                        rdr.extend(wtr[8 - $bytes..].iter().map(|&x|x));
+                        let mut rdr = Cursor::new(rdr);
+                        n == rdr.$read::<BigEndian>($bytes).unwrap()
+                    }
+                    qc_sized(prop as fn($ty_int) -> bool, max);
+                }
+
+                #[test]
+                fn little_endian() {
+                    let max = ($max - 1) >> (8 * (8 - $bytes));
+                    fn prop(n: $ty_int) -> bool {
+                        let mut wtr = vec![];
+                        wtr.$write::<LittleEndian>(n).unwrap();
+                        let mut rdr = Cursor::new(wtr);
+                        n == rdr.$read::<LittleEndian>($bytes).unwrap()
+                    }
+                    qc_sized(prop as fn($ty_int) -> bool, max);
+                }
+
+                #[test]
+                fn native_endian() {
+                    let max = ($max - 1) >> (8 * (8 - $bytes));
+                    fn prop(n: $ty_int) -> bool {
+                        let mut wtr = vec![];
+                        wtr.$write::<NativeEndian>(n).unwrap();
+                        let mut rdr = Cursor::new(wtr);
+                        n == rdr.$read::<NativeEndian>($bytes).unwrap()
+                    }
+                    qc_sized(prop as fn($ty_int) -> bool, max);
+                }
+            }
+        );
+        ($name:ident, $ty_int:ident, $max:expr, $read:ident, $write:ident) => (
+            mod $name {
+                use std::io::Cursor;
+                use {
+                    ReadBytesExt, WriteBytesExt,
+                    BigEndian, NativeEndian, LittleEndian,
+                };
+                use test::qc_sized;
+
+                #[test]
+                fn big_endian() {
+                    fn prop(n: $ty_int) -> bool {
+                        let mut wtr = vec![];
+                        wtr.$write::<BigEndian>(n).unwrap();
+                        let mut rdr = Cursor::new(wtr);
+                        n == rdr.$read::<BigEndian>().unwrap()
+                    }
+                    qc_sized(prop as fn($ty_int) -> bool, $max - 1);
+                }
+
+                #[test]
+                fn little_endian() {
+                    fn prop(n: $ty_int) -> bool {
+                        let mut wtr = vec![];
+                        wtr.$write::<LittleEndian>(n).unwrap();
+                        let mut rdr = Cursor::new(wtr);
+                        n == rdr.$read::<LittleEndian>().unwrap()
+                    }
+                    qc_sized(prop as fn($ty_int) -> bool, $max - 1);
+                }
+
+                #[test]
+                fn native_endian() {
+                    fn prop(n: $ty_int) -> bool {
+                        let mut wtr = vec![];
+                        wtr.$write::<NativeEndian>(n).unwrap();
+                        let mut rdr = Cursor::new(wtr);
+                        n == rdr.$read::<NativeEndian>().unwrap()
+                    }
+                    qc_sized(prop as fn($ty_int) -> bool, $max - 1);
+                }
+            }
+        );
+    }
+
+    qc_bytes_ext!(prop_ext_u16, u16, ::std::u16::MAX as u64, read_u16, write_u16);
+    qc_bytes_ext!(prop_ext_i16, i16, ::std::i16::MAX as u64, read_i16, write_i16);
+    qc_bytes_ext!(prop_ext_u32, u32, ::std::u32::MAX as u64, read_u32, write_u32);
+    qc_bytes_ext!(prop_ext_i32, i32, ::std::i32::MAX as u64, read_i32, write_i32);
+    qc_bytes_ext!(prop_ext_u64, u64, ::std::u64::MAX as u64, read_u64, write_u64);
+    qc_bytes_ext!(prop_ext_i64, i64, ::std::i64::MAX as u64, read_i64, write_i64);
+    qc_bytes_ext!(prop_ext_f32, f32, ::std::u64::MAX as u64, read_f32, write_f32);
+    qc_bytes_ext!(prop_ext_f64, f64, ::std::i64::MAX as u64, read_f64, write_f64);
+
+    qc_bytes_ext!(prop_ext_uint_1, u64, ::test::U64_MAX, 1, read_uint, write_u64);
+    qc_bytes_ext!(prop_ext_uint_2, u64, ::test::U64_MAX, 2, read_uint, write_u64);
+    qc_bytes_ext!(prop_ext_uint_3, u64, ::test::U64_MAX, 3, read_uint, write_u64);
+    qc_bytes_ext!(prop_ext_uint_4, u64, ::test::U64_MAX, 4, read_uint, write_u64);
+    qc_bytes_ext!(prop_ext_uint_5, u64, ::test::U64_MAX, 5, read_uint, write_u64);
+    qc_bytes_ext!(prop_ext_uint_6, u64, ::test::U64_MAX, 6, read_uint, write_u64);
+    qc_bytes_ext!(prop_ext_uint_7, u64, ::test::U64_MAX, 7, read_uint, write_u64);
+    qc_bytes_ext!(prop_ext_uint_8, u64, ::test::U64_MAX, 8, read_uint, write_u64);
+
+    qc_bytes_ext!(prop_ext_int_1, i64, ::test::I64_MAX, 1, read_int, write_i64);
+    qc_bytes_ext!(prop_ext_int_2, i64, ::test::I64_MAX, 2, read_int, write_i64);
+    qc_bytes_ext!(prop_ext_int_3, i64, ::test::I64_MAX, 3, read_int, write_i64);
+    qc_bytes_ext!(prop_ext_int_4, i64, ::test::I64_MAX, 4, read_int, write_i64);
+    qc_bytes_ext!(prop_ext_int_5, i64, ::test::I64_MAX, 5, read_int, write_i64);
+    qc_bytes_ext!(prop_ext_int_6, i64, ::test::I64_MAX, 6, read_int, write_i64);
+    qc_bytes_ext!(prop_ext_int_7, i64, ::test::I64_MAX, 7, read_int, write_i64);
+    qc_bytes_ext!(prop_ext_int_8, i64, ::test::I64_MAX, 8, read_int, write_i64);
+}
+
--- a/toolkit/library/gtest/rust/Cargo.lock
+++ b/toolkit/library/gtest/rust/Cargo.lock
@@ -4,22 +4,22 @@ version = "0.1.0"
 dependencies = [
  "gkrust-shared 0.1.0",
  "mp4parse-gtest 0.1.0",
  "nsstring-gtest 0.1.0",
 ]
 
 [[package]]
 name = "bitreader"
-version = "0.1.0"
+version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "byteorder"
-version = "0.5.3"
+version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "gkrust-shared"
 version = "0.1.0"
 dependencies = [
  "mp4parse_capi 0.6.0",
  "nsstring 0.1.0",
@@ -45,29 +45,29 @@ source = "registry+https://github.com/ru
 name = "matches"
 version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "mp4parse"
 version = "0.6.0"
 dependencies = [
- "bitreader 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitreader 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "mp4parse-gtest"
 version = "0.1.0"
 
 [[package]]
 name = "mp4parse_capi"
 version = "0.6.0"
 dependencies = [
- "byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "mp4parse 0.6.0",
 ]
 
 [[package]]
 name = "nsstring"
 version = "0.1.0"
 
 [[package]]
@@ -104,16 +104,16 @@ name = "url"
 version = "1.2.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "idna 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "matches 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [metadata]
-"checksum bitreader 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b245039eddbd1a051b8bfa5d5b6afaad6d34d172057a15d561e80b50b4978e8d"
-"checksum byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0fc10e8cc6b2580fda3f36eb6dc5316657f812a3df879a44a66fc9f0fdbc4855"
+"checksum bitreader 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8319aa6588c40cce19a135009ec70dc730a34ed9d27bab2409298b948546da7a"
+"checksum byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c40977b0ee6b9885c9013cd41d9feffdd22deb3bb4dc3a71d901cc7a77de18c8"
 "checksum idna 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1053236e00ce4f668aeca4a769a09b3bf5a682d802abd6f3cb39374f6b162c11"
 "checksum libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "a51822fc847e7a8101514d1d44e354ba2ffa7d4c194dcab48870740e327cac70"
 "checksum matches 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bcc3ad8109fa4b522f9b0cd81440422781f564aaf8c195de6b9d6642177ad0dd"
 "checksum unicode-bidi 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c1f7ceb96afdfeedee42bade65a0d585a6a0106f681b6749c8ff4daa8df30b3f"
 "checksum unicode-normalization 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "26643a2f83bac55f1976fb716c10234485f9202dcd65cfbdf9da49867b271172"
 "checksum url 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f024e241a55f5c88401595adc1d4af0c9649e91da82d0e190fe55950231ae575"
--- a/toolkit/library/rust/Cargo.lock
+++ b/toolkit/library/rust/Cargo.lock
@@ -2,22 +2,22 @@
 name = "gkrust"
 version = "0.1.0"
 dependencies = [
  "gkrust-shared 0.1.0",
 ]
 
 [[package]]
 name = "bitreader"
-version = "0.1.0"
+version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "byteorder"
-version = "0.5.3"
+version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "gkrust-shared"
 version = "0.1.0"
 dependencies = [
  "mp4parse_capi 0.6.0",
  "nsstring 0.1.0",
@@ -43,25 +43,25 @@ source = "registry+https://github.com/ru
 name = "matches"
 version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "mp4parse"
 version = "0.6.0"
 dependencies = [
- "bitreader 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitreader 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "mp4parse_capi"
 version = "0.6.0"
 dependencies = [
- "byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "mp4parse 0.6.0",
 ]
 
 [[package]]
 name = "nsstring"
 version = "0.1.0"
 
 [[package]]
@@ -91,16 +91,16 @@ name = "url"
 version = "1.2.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "idna 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "matches 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [metadata]
-"checksum bitreader 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b245039eddbd1a051b8bfa5d5b6afaad6d34d172057a15d561e80b50b4978e8d"
-"checksum byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0fc10e8cc6b2580fda3f36eb6dc5316657f812a3df879a44a66fc9f0fdbc4855"
+"checksum bitreader 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8319aa6588c40cce19a135009ec70dc730a34ed9d27bab2409298b948546da7a"
+"checksum byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c40977b0ee6b9885c9013cd41d9feffdd22deb3bb4dc3a71d901cc7a77de18c8"
 "checksum idna 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1053236e00ce4f668aeca4a769a09b3bf5a682d802abd6f3cb39374f6b162c11"
 "checksum libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "a51822fc847e7a8101514d1d44e354ba2ffa7d4c194dcab48870740e327cac70"
 "checksum matches 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bcc3ad8109fa4b522f9b0cd81440422781f564aaf8c195de6b9d6642177ad0dd"
 "checksum unicode-bidi 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c1f7ceb96afdfeedee42bade65a0d585a6a0106f681b6749c8ff4daa8df30b3f"
 "checksum unicode-normalization 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "26643a2f83bac55f1976fb716c10234485f9202dcd65cfbdf9da49867b271172"
 "checksum url 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f024e241a55f5c88401595adc1d4af0c9649e91da82d0e190fe55950231ae575"