core: Half-implement an H.263 decoder

This commit is contained in:
David Wendt 2020-12-04 23:10:35 -05:00 committed by kmeisthax
parent 7b9049cedf
commit 885805f887
3 changed files with 60 additions and 9 deletions

12
Cargo.lock generated
View File

@ -1694,6 +1694,17 @@ dependencies = [
"bitflags",
]
[[package]]
name = "h263-rs"
version = "0.1.0"
source = "git+https://github.com/ruffle-rs/h263-rs?rev=837f075d280680abc8dd3fc3d47656d5a770c48e#837f075d280680abc8dd3fc3d47656d5a770c48e"
dependencies = [
"bitflags",
"lazy_static",
"num-traits",
"thiserror",
]
[[package]]
name = "hashbrown"
version = "0.9.1"
@ -3027,6 +3038,7 @@ dependencies = [
"gc-arena-derive",
"generational-arena",
"gif",
"h263-rs",
"indexmap",
"instant",
"jpeg-decoder",

View File

@ -36,6 +36,7 @@ encoding_rs = "0.8.28"
rand = { version = "0.8.4", features = ["std", "small_rng"], default-features = false }
serde = { version = "1.0.127", features = ["derive"], optional = true }
nellymoser-rs = { git = "https://github.com/ruffle-rs/nellymoser" }
h263-rs = { git = "https://github.com/ruffle-rs/h263-rs", rev = "837f075d280680abc8dd3fc3d47656d5a770c48e" }
regress = "0.4"
flash-lso = { git = "https://github.com/ruffle-rs/rust-flash-lso", rev = "19fecd07b9888c4bdaa66771c468095783b52bed" }
json = "0.12.4"

View File

@ -5,10 +5,14 @@ use crate::backend::video::{
EncodedFrame, Error, FrameDependency, VideoBackend, VideoStreamHandle,
};
use generational_arena::Arena;
use h263_rs::parser::{decode_picture, H263Reader};
use h263_rs::{DecoderOption, H263State, PictureTypeCode};
use swf::{VideoCodec, VideoDeblocking};
/// A single preloaded video stream.
pub enum VideoStream {}
pub enum VideoStream {
H263(H263State),
}
/// Software video backend that proxies to CPU-only codec implementations that
/// ship with Ruffle.
@ -38,33 +42,67 @@ impl VideoBackend for SoftwareVideoBackend {
codec: VideoCodec,
_filter: VideoDeblocking,
) -> Result<VideoStreamHandle, Error> {
Err(format!("Unsupported video codec type {:?}", codec).into())
match codec {
VideoCodec::H263 => Ok(self.streams.insert(VideoStream::H263(H263State::new(
DecoderOption::SORENSON_SPARK_BITSTREAM,
)))),
_ => Err(format!("Unsupported video codec type {:?}", codec).into()),
}
}
fn preload_video_stream_frame(
&mut self,
stream: VideoStreamHandle,
_encoded_frame: EncodedFrame<'_>,
encoded_frame: EncodedFrame<'_>,
) -> Result<FrameDependency, Error> {
let _stream = self
let stream = self
.streams
.get_mut(stream)
.ok_or("Unregistered video stream")?;
unreachable!()
match stream {
VideoStream::H263(state) => {
let mut reader = H263Reader::from_source(encoded_frame.data());
let picture =
decode_picture(&mut reader, DecoderOption::SORENSON_SPARK_BITSTREAM, None)?
.ok_or("Picture in video stream is not a picture")?;
match picture.picture_type {
PictureTypeCode::IFrame => Ok(FrameDependency::None),
PictureTypeCode::PFrame => Ok(FrameDependency::Past),
PictureTypeCode::DisposablePFrame => Ok(FrameDependency::Past),
_ => Err("Invalid picture type code!".into()),
}
}
}
}
fn decode_video_stream_frame(
&mut self,
stream: VideoStreamHandle,
_encoded_frame: EncodedFrame<'_>,
_renderer: &mut dyn RenderBackend,
encoded_frame: EncodedFrame<'_>,
renderer: &mut dyn RenderBackend,
) -> Result<BitmapInfo, Error> {
let _stream = self
let stream = self
.streams
.get_mut(stream)
.ok_or("Unregistered video stream")?;
unreachable!()
match stream {
VideoStream::H263(state) => {
let mut reader = H263Reader::from_source(encoded_frame.data());
state.decode_next_picture(&mut reader)?;
let picture = state
.get_last_picture()
.expect("Decoding a picture should let us grab that picture");
//TODO: YUV 4:2:0 decoding
//TODO: Construct a bitmap drawable for the renderer and hand
//it back
unimplemented!("oops");
}
}
}
}