Focus on Webm case specifically to get working code
can retry generic EBML later
This commit is contained in:
parent
11bb7f4412
commit
56a7284e32
6 changed files with 39 additions and 53 deletions
|
@ -32,7 +32,7 @@ impl Service for WebmServer {
|
|||
let stream: BodyStream<Vec<u8>> = Box::new(
|
||||
repeat(()).take(10)
|
||||
.map(|()|
|
||||
parse_webm(SRC_FILE).into_iter().chunk_webm()
|
||||
parse_webm(SRC_FILE).chunk_webm()
|
||||
).flatten()
|
||||
.fix_timecodes()
|
||||
.map_err(|err| match err {
|
||||
|
|
20
src/chunk.rs
20
src/chunk.rs
|
@ -1,9 +1,7 @@
|
|||
use futures::{Async, Stream};
|
||||
use std::io::Cursor;
|
||||
use std::marker::PhantomData;
|
||||
use std::mem;
|
||||
use std::sync::Arc;
|
||||
use ebml::EbmlEventSource;
|
||||
use webm::*;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
@ -89,13 +87,12 @@ pub enum ChunkingError<E> {
|
|||
OtherError(E)
|
||||
}
|
||||
|
||||
pub struct WebmChunker<'a, S: EbmlEventSource<'a>> {
|
||||
pub struct WebmChunker<S: WebmEventSource> {
|
||||
source: S,
|
||||
state: ChunkerState,
|
||||
_marker: PhantomData<&'a [u8]>
|
||||
state: ChunkerState
|
||||
}
|
||||
|
||||
impl<'a, S: EbmlEventSource<'a, Event = WebmElement<'a>>> Stream for WebmChunker<'a, S>
|
||||
impl<'a, S: WebmEventSource> Stream for WebmChunker<S>
|
||||
{
|
||||
type Item = Chunk;
|
||||
type Error = ChunkingError<S::Error>;
|
||||
|
@ -212,16 +209,15 @@ impl<'a, S: EbmlEventSource<'a, Event = WebmElement<'a>>> Stream for WebmChunker
|
|||
}
|
||||
}
|
||||
|
||||
pub trait WebmStream<'a, T: EbmlEventSource<'a, Event = WebmElement<'a>>> {
|
||||
fn chunk_webm(self) -> WebmChunker<'a, T>;
|
||||
pub trait WebmStream<T: WebmEventSource> {
|
||||
fn chunk_webm(self) -> WebmChunker<T>;
|
||||
}
|
||||
|
||||
impl<'a, T: EbmlEventSource<'a, Event = WebmElement<'a>>> WebmStream<'a, T> for T {
|
||||
fn chunk_webm(self) -> WebmChunker<'a, T> {
|
||||
impl<'a, T: WebmEventSource> WebmStream<T> for T {
|
||||
fn chunk_webm(self) -> WebmChunker<T> {
|
||||
WebmChunker {
|
||||
source: self,
|
||||
state: ChunkerState::BuildingHeader(Cursor::new(Vec::new())),
|
||||
_marker: PhantomData
|
||||
state: ChunkerState::BuildingHeader(Cursor::new(Vec::new()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
13
src/ebml.rs
13
src/ebml.rs
|
@ -3,7 +3,6 @@ use futures::Async;
|
|||
use std::error::Error as ErrorTrait;
|
||||
use std::fmt::{Display, Formatter, Result as FmtResult};
|
||||
use std::io::{Cursor, Error as IoError, ErrorKind, Result as IoResult, Write, Seek, SeekFrom};
|
||||
use std::marker::PhantomData;
|
||||
|
||||
pub const EBML_HEAD_ID: u64 = 0x0A45DFA3;
|
||||
pub const DOC_TYPE_ID: u64 = 0x0282;
|
||||
|
@ -216,9 +215,8 @@ pub fn encode_integer<T: Write>(tag: u64, value: u64, output: &mut T) -> IoResul
|
|||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct Ebml<Source, Element> {
|
||||
pub source: Source,
|
||||
_marker: PhantomData<fn() -> Element>
|
||||
pub struct Ebml<Source> {
|
||||
pub source: Source
|
||||
}
|
||||
|
||||
pub trait FromEbml<'b>: Sized {
|
||||
|
@ -251,13 +249,6 @@ pub trait FromEbml<'b>: Sized {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn parse<T>(source: T) -> Ebml<T, Self> {
|
||||
Ebml {
|
||||
source: source,
|
||||
_marker: PhantomData
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait EbmlEventSource<'a> {
|
||||
|
|
|
@ -1,32 +1,26 @@
|
|||
use std::marker::PhantomData;
|
||||
use futures::Async;
|
||||
use ebml::*;
|
||||
use webm::*;
|
||||
|
||||
pub struct EbmlIterator<'b, T: FromEbml<'b>> {
|
||||
slice: &'b[u8],
|
||||
position: usize,
|
||||
_marker: PhantomData<fn() -> T>
|
||||
pub struct EbmlCursor<T> {
|
||||
source: T,
|
||||
position: usize
|
||||
}
|
||||
|
||||
impl<'b, E: FromEbml<'b>> IntoIterator for Ebml<&'b[u8], E> {
|
||||
type Item = E;
|
||||
type IntoIter = EbmlIterator<'b, E>;
|
||||
|
||||
fn into_iter(self) -> EbmlIterator<'b, E>
|
||||
{
|
||||
EbmlIterator {
|
||||
slice: self.source,
|
||||
position: 0,
|
||||
_marker: PhantomData
|
||||
impl<T> EbmlCursor<T> {
|
||||
pub fn new(source: T) -> Self {
|
||||
EbmlCursor {
|
||||
source,
|
||||
position: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'b, T: FromEbml<'b>> Iterator for EbmlIterator<'b, T> {
|
||||
type Item = T;
|
||||
impl<'a> Iterator for EbmlCursor<&'a [u8]> {
|
||||
type Item = WebmElement<'a>;
|
||||
|
||||
fn next(&mut self) -> Option<T> {
|
||||
match Self::Item::decode_element(&self.slice[self.position..]) {
|
||||
fn next(&mut self) -> Option<WebmElement<'a>> {
|
||||
match Self::Item::decode_element(&self.source[self.position..]) {
|
||||
Err(_) => None,
|
||||
Ok(None) => None,
|
||||
Ok(Some((element, element_size))) => {
|
||||
|
@ -37,12 +31,11 @@ impl<'b, T: FromEbml<'b>> Iterator for EbmlIterator<'b, T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, T: FromEbml<'a>> EbmlEventSource<'a> for EbmlIterator<'a, T> {
|
||||
type Event = T;
|
||||
impl<'b, T: AsRef<[u8]>> WebmEventSource for EbmlCursor<T> {
|
||||
type Error = Error;
|
||||
|
||||
fn poll_event(&'a mut self) -> Result<Async<Option<T>>, Error> {
|
||||
match Self::Event::decode_element(&self.slice[self.position..]) {
|
||||
fn poll_event<'a>(&'a mut self) -> Result<Async<Option<WebmElement<'a>>>, Error> {
|
||||
match WebmElement::decode_element(&self.source.as_ref()[self.position..]) {
|
||||
Err(err) => Err(err),
|
||||
Ok(None) => Ok(Async::Ready(None)),
|
||||
Ok(Some((element, element_size))) => {
|
||||
|
|
11
src/webm.rs
11
src/webm.rs
|
@ -1,6 +1,8 @@
|
|||
use std::io::{Cursor, Error as IoError, ErrorKind, Result as IoResult, Write, Seek};
|
||||
use bytes::{BigEndian, BufMut, ByteOrder};
|
||||
use futures::Async;
|
||||
use ebml::*;
|
||||
use iterator::EbmlCursor;
|
||||
|
||||
const SEGMENT_ID: u64 = 0x08538067;
|
||||
const SEEK_HEAD_ID: u64 = 0x014D9B74;
|
||||
|
@ -11,8 +13,8 @@ const CLUSTER_ID: u64 = 0x0F43B675;
|
|||
const TIMECODE_ID: u64 = 0x67;
|
||||
const SIMPLE_BLOCK_ID: u64 = 0x23;
|
||||
|
||||
pub fn parse_webm<'a, T: 'a>(source: T) -> Ebml<T, WebmElement<'a>> {
|
||||
WebmElement::parse(source)
|
||||
pub fn parse_webm<T: AsRef<[u8]>>(source: T) -> EbmlCursor<T> {
|
||||
EbmlCursor::new(source)
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Copy, Clone)]
|
||||
|
@ -125,6 +127,11 @@ pub fn encode_webm_element<T: Write + Seek>(element: &WebmElement, output: &mut
|
|||
}
|
||||
}
|
||||
|
||||
pub trait WebmEventSource {
|
||||
type Error;
|
||||
fn poll_event<'a>(&'a mut self) -> Result<Async<Option<WebmElement<'a>>>, Self::Error>;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use tests::TEST_FILE;
|
||||
|
|
|
@ -71,12 +71,11 @@ impl<I: AsRef<[u8]>, S: Stream<Item = I>> WebmStream<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, I: AsRef<[u8]>, S: Stream<Item = I>> EbmlEventSource<'a> for WebmStream<S> {
|
||||
type Event = WebmElement<'a>;
|
||||
impl<I: AsRef<[u8]>, S: Stream<Item = I>> WebmEventSource for WebmStream<S> {
|
||||
type Error = ParsingError<S::Error>;
|
||||
|
||||
fn poll_event(&'a mut self) -> Result<Async<Option<Self::Event>>, Self::Error> {
|
||||
return WebmStream::poll_event(&mut self);
|
||||
fn poll_event<'a>(&'a mut self) -> Result<Async<Option<WebmElement<'a>>>, Self::Error> {
|
||||
return WebmStream::poll_event(self);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue