From a00d43e124b2d8b5c49c59e65911ef93607413c9 Mon Sep 17 00:00:00 2001 From: Tangent 128 Date: Sat, 1 Jul 2017 01:30:43 -0400 Subject: [PATCH] Implement decode_simple_block --- Cargo.toml | 1 + src/bin/dump.rs | 2 +- src/lib.rs | 1 + src/webm.rs | 31 ++++++++++++++++++++++++++++--- 4 files changed, 31 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 861f132..e961060 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,4 +4,5 @@ version = "0.1.0" authors = ["Tangent 128 "] [dependencies] +byteorder = "1" futures = "^0.1.7" diff --git a/src/bin/dump.rs b/src/bin/dump.rs index 1251c9a..8443dcd 100644 --- a/src/bin/dump.rs +++ b/src/bin/dump.rs @@ -22,7 +22,7 @@ pub fn main() { match element { // suppress printing byte arrays Tracks(slice) => println!("Tracks[{}]", slice.len()), - Cluster(slice) => println!("Cluster[{}]", slice.len()), + SimpleBlock{timecode, ..} => println!("SimpleBlock@{}", timecode), other => println!("{:?}", other) } } diff --git a/src/lib.rs b/src/lib.rs index f30276a..9c5fe78 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,5 @@ +extern crate byteorder; extern crate futures; pub mod ebml; diff --git a/src/webm.rs b/src/webm.rs index 3908c31..75c2573 100644 --- a/src/webm.rs +++ b/src/webm.rs @@ -1,3 +1,4 @@ +use byteorder::{BigEndian, ByteOrder}; use ebml::*; const SEGMENT_ID: u64 = 0x08538067; @@ -21,7 +22,12 @@ pub enum WebmElement<'b> { Tracks(&'b[u8]), Cluster, Timecode(u64), - SimpleBlock(&'b[u8]), + SimpleBlock { + track: u64, + timecode: i16, + flags: u8, + data: &'b[u8] + }, Unknown(u64) } @@ -47,13 +53,32 @@ impl<'a> Schema<'a> for Webm { CUES_ID => Ok(WebmElement::Cues), TRACKS_ID => Ok(WebmElement::Tracks(bytes)), CLUSTER_ID => Ok(WebmElement::Cluster), - TIMECODE_ID => Ok(WebmElement::Timecode(0)), - SIMPLE_BLOCK_ID => Ok(WebmElement::SimpleBlock(bytes)), + TIMECODE_ID => decode_uint(bytes).map(WebmElement::Timecode), + SIMPLE_BLOCK_ID => decode_simple_block(bytes), _ => Ok(WebmElement::Unknown(element_id)) } } } +fn decode_simple_block(bytes: &[u8]) -> Result { + if let Ok(Some((Varint::Value(track), track_field_len))) = decode_varint(bytes) { + let header_len = track_field_len + 2 + 1; + if bytes.len() < header_len { + return Err(Error::CorruptPayload); + } + let timecode = BigEndian::read_i16(&bytes[track_field_len..]); + let flags = bytes[track_field_len + 2]; + return Ok(WebmElement::SimpleBlock { + track: track, + timecode: timecode, + flags: flags, + data: &bytes[header_len..], + }) + } else { + return Err(Error::CorruptPayload); + } +} + #[cfg(test)] mod tests { use tests::TEST_FILE;