aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKostya Shishkov <kostya.shishkov@gmail.com>2021-09-19 13:50:54 +0200
committerKostya Shishkov <kostya.shishkov@gmail.com>2021-09-30 18:13:21 +0200
commita715e99fd5a8b724cf31877c74bbd8191d7fd256 (patch)
tree219bfed169b08e101b6b19300b37680dddfaf140
parentdbb2cbc9c1274135470608275c1893a201cba731 (diff)
downloadnihav-a715e99fd5a8b724cf31877c74bbd8191d7fd256.tar.gz
introduce raw video "codec"
-rw-r--r--nihav-commonfmt/Cargo.toml3
-rw-r--r--nihav-commonfmt/src/codecs/mod.rs4
-rw-r--r--nihav-commonfmt/src/codecs/rawvideo.rs107
-rw-r--r--nihav-registry/src/register.rs3
4 files changed, 116 insertions, 1 deletions
diff --git a/nihav-commonfmt/Cargo.toml b/nihav-commonfmt/Cargo.toml
index 1ac7261..7f4cc4f 100644
--- a/nihav-commonfmt/Cargo.toml
+++ b/nihav-commonfmt/Cargo.toml
@@ -34,9 +34,10 @@ muxer_wav = ["muxers"]
all_decoders = ["all_video_decoders", "all_audio_decoders"]
-all_video_decoders = ["decoder_cinepak", "decoder_clearvideo", "decoder_zmbv"]
+all_video_decoders = ["decoder_cinepak", "decoder_clearvideo", "decoder_rawvideo", "decoder_zmbv"]
decoder_cinepak = ["decoders"]
decoder_clearvideo = ["decoders"]
+decoder_rawvideo = ["decoders"]
decoder_zmbv = ["decoders"]
all_audio_decoders = ["decoder_pcm", "decoder_ts102366", "decoder_sipro", "decoder_atrac3", "decoder_aac"]
diff --git a/nihav-commonfmt/src/codecs/mod.rs b/nihav-commonfmt/src/codecs/mod.rs
index 7fef1cb..2c9eef7 100644
--- a/nihav-commonfmt/src/codecs/mod.rs
+++ b/nihav-commonfmt/src/codecs/mod.rs
@@ -8,6 +8,8 @@ macro_rules! validate {
mod cinepak;
#[cfg(feature="decoder_clearvideo")]
mod clearvideo;
+#[cfg(feature="decoder_rawvideo")]
+mod rawvideo;
#[cfg(feature="decoder_zmbv")]
mod zmbv;
@@ -36,6 +38,8 @@ const DECODERS: &[DecoderInfo] = &[
DecoderInfo { name: "clearvideo", get_decoder: clearvideo::get_decoder },
#[cfg(feature="decoder_clearvideo")]
DecoderInfo { name: "clearvideo_rm", get_decoder: clearvideo::get_decoder_rm },
+#[cfg(feature="decoder_rawvideo")]
+ DecoderInfo { name: "rawvideo", get_decoder: rawvideo::get_decoder },
#[cfg(feature="decoder_zmbv")]
DecoderInfo { name: "zmbv", get_decoder: zmbv::get_decoder },
diff --git a/nihav-commonfmt/src/codecs/rawvideo.rs b/nihav-commonfmt/src/codecs/rawvideo.rs
new file mode 100644
index 0000000..fd1c0c3
--- /dev/null
+++ b/nihav-commonfmt/src/codecs/rawvideo.rs
@@ -0,0 +1,107 @@
+use nihav_core::codecs::*;
+
+struct RawDecoder {
+ info: NACodecInfoRef,
+}
+
+impl RawDecoder {
+ fn new() -> Self {
+ Self {
+ info: NACodecInfo::new_dummy(),
+ }
+ }
+}
+
+impl NADecoder for RawDecoder {
+ fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
+ if let NACodecTypeInfo::Video(_vinfo) = info.get_properties() {
+ self.info = info.clone();
+ Ok(())
+ } else {
+ Err(DecoderError::InvalidData)
+ }
+ }
+ fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
+ if let NACodecTypeInfo::Video(ref vinfo) = self.info.get_properties() {
+ let src = pkt.get_buffer();
+ let width = vinfo.width;
+ let height = vinfo.height;
+ let ncomp = vinfo.format.components as usize;
+ let buf = if vinfo.format.is_unpacked() && vinfo.format.get_max_depth() == 8 {
+ let mut offs = vec![0; ncomp];
+ let mut strides = Vec::with_capacity(ncomp);
+ let mut sizes = Vec::with_capacity(ncomp);
+ for chr in vinfo.format.comp_info[..ncomp].iter() {
+ if let Some(chromaton) = chr {
+ let stride = chromaton.get_linesize(width);
+ let size = stride * chromaton.get_height(height);
+ sizes.push(size);
+ strides.push(stride);
+ } else {
+ return Err(DecoderError::InvalidData);
+ }
+ }
+ let mut off = 0;
+ for i in 0..ncomp {
+ for (cno, chr) in vinfo.format.comp_info[..ncomp].iter().enumerate() {
+ if let Some(chromaton) = chr {
+ let comp_off = chromaton.comp_offs as usize;
+ validate!(comp_off < ncomp);
+ if comp_off != i {
+ continue;
+ }
+ offs[cno] = off;
+ off += sizes[i];
+ }
+ }
+ }
+ validate!(off == src.len());
+
+ NABufferType::Video(NAVideoBuffer::from_raw_parts(vinfo.clone(), src.clone(), offs, strides).into_ref())
+ } else {
+ let offs = vec![0; ncomp];
+ let strides = vec![0; ncomp];
+ NABufferType::VideoPacked(NAVideoBuffer::from_raw_parts(vinfo.clone(), src.clone(), offs, strides).into_ref())
+ };
+
+ let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), buf);
+ frm.set_keyframe(true);
+ frm.set_frame_type(FrameType::I);
+ Ok(frm.into_ref())
+ } else {
+ Err(DecoderError::Bug)
+ }
+ }
+ fn flush(&mut self) {}
+}
+
+
+impl NAOptionHandler for RawDecoder {
+ fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
+ fn set_options(&mut self, _options: &[NAOption]) { }
+ fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
+}
+
+pub fn get_decoder() -> Box<dyn NADecoder + Send> {
+ Box::new(RawDecoder::new())
+}
+
+#[cfg(test)]
+mod test {
+ use nihav_core::codecs::RegisteredDecoders;
+ use nihav_core::demuxers::RegisteredDemuxers;
+ use nihav_codec_support::test::dec_video::*;
+ use crate::generic_register_all_decoders;
+ use crate::generic_register_all_demuxers;
+ #[test]
+ fn test_rawvideo() {
+ let mut dmx_reg = RegisteredDemuxers::new();
+ generic_register_all_demuxers(&mut dmx_reg);
+ let mut dec_reg = RegisteredDecoders::new();
+ generic_register_all_decoders(&mut dec_reg);
+ test_decoding("yuv4mpeg", "rawvideo", "assets/Misc/test.y4m", None, &dmx_reg,
+ &dec_reg, ExpectedTestResult::MD5Frames(vec![
+ [0xd58326b0, 0xdbfc1dcc, 0x6d66a04c, 0x08a21bbb],
+ [0x9b2cb5c5, 0x69b5f261, 0xcaccaaaf, 0xff2a807d]]));
+ }
+}
diff --git a/nihav-registry/src/register.rs b/nihav-registry/src/register.rs
index 48d4541..d929e28 100644
--- a/nihav-registry/src/register.rs
+++ b/nihav-registry/src/register.rs
@@ -185,6 +185,9 @@ static CODEC_REGISTER: &[CodecDescription] = &[
desc!(audio; "atrac3", "Sony Atrac3"),
desc!(audio; "sipro", "Sipro Labs ADPCM"),
+
+ desc!(video-ll; "rawvideo", "Raw video data"),
+
desc!(video; "cinepak", "Cinepak"),
desc!(video-llp; "zmbv", "Zip Motion Blocks Video"),