]> git.nihav.org Git - nihav.git/commitdiff
h264: split decoder into common and 8-bit specific decoding parts
authorKostya Shishkov <kostya.shishkov@gmail.com>
Sat, 7 Mar 2026 13:06:36 +0000 (14:06 +0100)
committerKostya Shishkov <kostya.shishkov@gmail.com>
Sat, 7 Mar 2026 17:45:46 +0000 (18:45 +0100)
This is a preparation for future high-bitdepth support.

20 files changed:
nihav-itu/src/codecs/h264/baseline/cabac.rs [moved from nihav-itu/src/codecs/h264/cabac.rs with 99% similarity]
nihav-itu/src/codecs/h264/baseline/cavlc.rs [moved from nihav-itu/src/codecs/h264/cavlc.rs with 99% similarity]
nihav-itu/src/codecs/h264/baseline/decoder_mt.rs [moved from nihav-itu/src/codecs/h264/decoder_mt.rs with 99% similarity]
nihav-itu/src/codecs/h264/baseline/decoder_st.rs [moved from nihav-itu/src/codecs/h264/decoder_st.rs with 99% similarity]
nihav-itu/src/codecs/h264/baseline/dispatch.rs [moved from nihav-itu/src/codecs/h264/dispatch.rs with 99% similarity]
nihav-itu/src/codecs/h264/baseline/dsp/mc/debug.rs [moved from nihav-itu/src/codecs/h264/dsp/mc/debug.rs with 100% similarity]
nihav-itu/src/codecs/h264/baseline/dsp/mc/mod.rs [moved from nihav-itu/src/codecs/h264/dsp/mc/mod.rs with 100% similarity]
nihav-itu/src/codecs/h264/baseline/dsp/mc/release.rs [moved from nihav-itu/src/codecs/h264/dsp/mc/release.rs with 100% similarity]
nihav-itu/src/codecs/h264/baseline/dsp/mc/x86/blockdsp.rs [moved from nihav-itu/src/codecs/h264/dsp/mc/x86/blockdsp.rs with 100% similarity]
nihav-itu/src/codecs/h264/baseline/dsp/mc/x86/chroma_mc.rs [moved from nihav-itu/src/codecs/h264/dsp/mc/x86/chroma_mc.rs with 100% similarity]
nihav-itu/src/codecs/h264/baseline/dsp/mc/x86/luma_mc.rs [moved from nihav-itu/src/codecs/h264/dsp/mc/x86/luma_mc.rs with 100% similarity]
nihav-itu/src/codecs/h264/baseline/dsp/mc/x86/mod.rs [moved from nihav-itu/src/codecs/h264/dsp/mc/x86/mod.rs with 100% similarity]
nihav-itu/src/codecs/h264/baseline/dsp/mod.rs [moved from nihav-itu/src/codecs/h264/dsp/mod.rs with 100% similarity]
nihav-itu/src/codecs/h264/baseline/loopfilter.rs [moved from nihav-itu/src/codecs/h264/loopfilter.rs with 100% similarity]
nihav-itu/src/codecs/h264/baseline/mb_recon.rs [moved from nihav-itu/src/codecs/h264/mb_recon.rs with 99% similarity]
nihav-itu/src/codecs/h264/baseline/mod.rs [new file with mode: 0644]
nihav-itu/src/codecs/h264/baseline/pic_ref.rs [moved from nihav-itu/src/codecs/h264/pic_ref.rs with 99% similarity]
nihav-itu/src/codecs/h264/baseline/types.rs [moved from nihav-itu/src/codecs/h264/types.rs with 68% similarity]
nihav-itu/src/codecs/h264/common_types.rs [new file with mode: 0644]
nihav-itu/src/codecs/h264/mod.rs

similarity index 99%
rename from nihav-itu/src/codecs/h264/cabac.rs
rename to nihav-itu/src/codecs/h264/baseline/cabac.rs
index ac9398218f705b4a48a70a61aa4367a478429e6d..1fa122cb8a8a37eaf2c5ca837601ff881167aba2 100644 (file)
@@ -1,9 +1,12 @@
 //use nihav_core::codecs::{DecoderResult, DecoderError};
 
+use nihav_codec_support::codecs::MV;
+
+use super::super::*;
 use super::*;
-use super::cabac_coder::*;
+use super::super::cabac_coder::*;
 use super::dsp::{CHROMA_DC_SCAN, ZIGZAG, ZIGZAG1, ZIGZAG8X8};
-use super::slice::SliceHeader;
+use super::super::slice::SliceHeader;
 
 pub fn cabac_decode_mbskip(cabac: &mut CABAC, sstate: &SliceState, slice_hdr: &SliceHeader) -> bool {
     let skip_idx = if slice_hdr.slice_type.is_p() { 11 } else { 24 };
similarity index 99%
rename from nihav-itu/src/codecs/h264/cavlc.rs
rename to nihav-itu/src/codecs/h264/baseline/cavlc.rs
index af98aa5a1cac61450c6a8da25df76ed2db2a893b..8d9b299c80cd894eeeea2e243d3964d0d9ef6b04 100644 (file)
@@ -1,10 +1,12 @@
 use nihav_core::codecs::{DecoderResult, DecoderError};
+use nihav_codec_support::codecs::MV;
 use nihav_core::io::bitreader::*;
 use nihav_core::io::codebook::*;
 use nihav_core::io::intcode::*;
+use super::super::*;
 use super::*;
 use super::dsp::{CHROMA_DC_SCAN, ZIGZAG, ZIGZAG1};
-use super::slice::SliceHeader;
+use super::super::slice::SliceHeader;
 
 fn map_i_type(idx: usize) -> MBType {
     if idx == 0 {
similarity index 99%
rename from nihav-itu/src/codecs/h264/decoder_mt.rs
rename to nihav-itu/src/codecs/h264/baseline/decoder_mt.rs
index fd1a800150d24900ceae5b00691cd04a29708bc4..216b810d754ab295fe66ab48b1cabf0d559a9978 100644 (file)
@@ -1,6 +1,7 @@
 use nihav_core::codecs::*;
 use nihav_core::io::bitreader::*;
 
+use super::super::*;
 use super::*;
 use super::dispatch::*;
 
similarity index 99%
rename from nihav-itu/src/codecs/h264/decoder_st.rs
rename to nihav-itu/src/codecs/h264/baseline/decoder_st.rs
index 149cf7466896e113d81e2377ffc080eb319eca7f..85771177ff60032dafd4b43a357a528e71af5758 100644 (file)
@@ -3,6 +3,7 @@ use std::sync::Arc;
 use nihav_core::codecs::*;
 use nihav_core::io::bitreader::*;
 
+use super::super::*;
 use super::*;
 
 struct H264Decoder {
similarity index 99%
rename from nihav-itu/src/codecs/h264/dispatch.rs
rename to nihav-itu/src/codecs/h264/baseline/dispatch.rs
index 75afb26fa1e8b5726de26ca3fa87a0f81b1a0e0c..e3e27fc20999633af9b3d096ca97d7acbd4ff7ae 100644 (file)
@@ -4,7 +4,8 @@ use std::thread;
 
 use nihav_core::codecs::{DecoderError, DecoderResult};
 
-use super::{FrameDecoder, PictureInfo, Shareable};
+use super::{FrameDecoder, PictureInfo};
+use super::super::Shareable;
 
 #[derive(Clone,Copy,Debug,PartialEq)]
 pub enum FrameDecodingStatus {
similarity index 99%
rename from nihav-itu/src/codecs/h264/mb_recon.rs
rename to nihav-itu/src/codecs/h264/baseline/mb_recon.rs
index dc7302dd10eb265a64a69869089d6c674cbcdb17..08fc30f118dc0ce6a226c0faffb4a2b236087401 100644 (file)
@@ -1,11 +1,12 @@
 use nihav_core::codecs::{DecoderResult, DecoderError};
 use nihav_core::frame::*;
 use nihav_codec_support::codecs::{MV, ZERO_MV};
-use super::{CurrentMBInfo, I4X4_SCAN, Shareable};
+use super::super::{CurrentMBInfo, I4X4_SCAN, Shareable};
+use super::super::common_types::*;
 use super::dispatch::{ThreadDispatcher, FrameDecodingStatus};
 use super::dsp::*;
 use super::pic_ref::SimplifiedSliceRefs;
-use super::slice::{SliceHeader, WeightInfo, DEF_WEIGHT_INFO};
+use super::super::slice::{SliceHeader, WeightInfo, DEF_WEIGHT_INFO};
 use super::types::*;
 
 fn pred_intra(frm: &mut NASimpleVideoFrame<u8>, sstate: &SliceState, mb_info: &CurrentMBInfo) {
diff --git a/nihav-itu/src/codecs/h264/baseline/mod.rs b/nihav-itu/src/codecs/h264/baseline/mod.rs
new file mode 100644 (file)
index 0000000..89606fc
--- /dev/null
@@ -0,0 +1,30 @@
+mod types;
+pub use types::*;
+mod pic_ref;
+pub use pic_ref::*;
+#[allow(clippy::identity_op)]
+#[allow(clippy::erasing_op)]
+#[allow(clippy::many_single_char_names)]
+#[allow(clippy::range_plus_one)]
+mod dsp;
+use dsp::*;
+mod cabac;
+use cabac::*;
+use super::cabac_coder::*;
+mod cavlc;
+use cavlc::*;
+mod loopfilter;
+use loopfilter::*;
+mod mb_recon;
+use mb_recon::*;
+use super::sets::*;
+use super::slice::*;
+
+mod decoder_st;
+pub use decoder_st::*;
+mod dispatch;
+mod decoder_mt;
+pub use decoder_mt::*;
+
+use super::common_types::*;
+
similarity index 99%
rename from nihav-itu/src/codecs/h264/pic_ref.rs
rename to nihav-itu/src/codecs/h264/baseline/pic_ref.rs
index b19f6331a8ae573fb360b383170c176b73731fc3..d01b7465a5a0e4dadc7c97bdf6c7d3d5828c1cc6 100644 (file)
@@ -2,8 +2,9 @@ use nihav_core::codecs::DecoderResult;
 use nihav_core::frame::{FrameType, NAVideoBufferRef, NATimeInfo};
 use nihav_core::refs::*;
 use nihav_codec_support::codecs::MV;
-use super::sets::SeqParameterSet;
-use super::slice::*;
+use super::super::common_types::*;
+use super::super::sets::SeqParameterSet;
+use super::super::slice::*;
 use super::types::*;
 
 #[derive(Clone)]
similarity index 68%
rename from nihav-itu/src/codecs/h264/types.rs
rename to nihav-itu/src/codecs/h264/baseline/types.rs
index 0cb3f8e784fe1307ae0bb39a2ab91c11a332632d..2f273a9104985414513a15fca410f6174d5f989f 100644 (file)
@@ -3,6 +3,7 @@ use nihav_codec_support::codecs::{MV, ZERO_MV};
 use nihav_codec_support::data::GenericCache;
 use super::SimplifiedSliceRefs;
 use super::pic_ref::FrameMBInfo;
+use super::super::common_types::*;
 
 #[derive(Clone,Copy)]
 pub struct SimpleFrame<'a> {
@@ -26,391 +27,6 @@ impl<'a> SimpleFrame<'a> {
     }
 }
 
-#[repr(u8)]
-#[derive(Clone,Copy,Debug,PartialEq)]
-pub enum BMode {
-    L0,
-    L1,
-    Bi,
-}
-
-#[derive(Clone,Copy,Debug,PartialEq,Default)]
-pub enum MBType {
-    #[default]
-    Intra4x4,
-    Intra8x8,
-    Intra16x16(u8, u8, u8),
-    PCM,
-
-    P16x16,
-    P16x8,
-    P8x16,
-    P8x8,
-    P8x8Ref0,
-    PSkip,
-
-    Direct,
-    B16x16(BMode),
-    B16x8(BMode, BMode),
-    B8x16(BMode, BMode),
-    B8x8,
-    BSkip,
-}
-
-impl MBType {
-    pub fn is_intra(self) -> bool {
-        matches!(self, MBType::Intra4x4 | MBType::Intra8x8 | MBType::Intra16x16(_, _, _) | MBType::PCM)
-    }
-    pub fn is_intra16x16(self) -> bool {
-        matches!(self, MBType::Intra16x16(_, _, _))
-    }
-    pub fn is_skip(self) -> bool {
-        matches!(self, MBType::PSkip | MBType::BSkip)
-    }
-    pub fn is_4x4(self) -> bool { self.num_parts() == 4 }
-    pub fn is_l0(self, part: usize) -> bool {
-        match self {
-            MBType::B16x16(mode) => mode == BMode::L0,
-            MBType::B16x8(mode0, mode1) | MBType::B8x16(mode0, mode1) => {
-                if part == 0 {
-                    mode0 == BMode::L0
-                } else {
-                    mode1 == BMode::L0
-                }
-            },
-            MBType::Direct | MBType::BSkip => false,
-            _ => true,
-        }
-    }
-    pub fn is_l1(self, part: usize) -> bool {
-        match self {
-            MBType::B16x16(mode) => mode == BMode::L1,
-            MBType::B16x8(mode0, mode1) | MBType::B8x16(mode0, mode1) => {
-                if part == 0 {
-                    mode0 == BMode::L1
-                } else {
-                    mode1 == BMode::L1
-                }
-            },
-            _ => false,
-        }
-    }
-    pub fn num_parts(self) -> usize {
-        match self {
-            MBType::Intra4x4 | MBType::Intra8x8 | MBType::Intra16x16(_, _, _) | MBType::PCM |
-            MBType::PSkip |
-            MBType::Direct | MBType::BSkip
-                => 1,
-            MBType::P16x16 |
-            MBType::B16x16(_)
-                => 1,
-            MBType::P16x8 | MBType::P8x16 |
-            MBType::B16x8(_, _) | MBType::B8x16(_, _)
-                => 2,
-            _ => 4,
-        }
-    }
-    pub fn size(self) -> (usize, usize) {
-        match self {
-            MBType::Intra4x4 |
-            MBType::Intra8x8 |
-            MBType::Intra16x16(_, _, _) |
-            MBType::PCM |
-            MBType::P16x16 |
-            MBType::PSkip |
-            MBType::Direct |
-            MBType::B16x16(_) |
-            MBType::BSkip
-                => (16, 16),
-            MBType::P16x8 | MBType::B16x8(_, _) => (16, 8),
-            MBType::P8x16 | MBType::B8x16(_, _) => (8, 16),
-            _ => (8, 8),
-        }
-    }
-}
-
-#[derive(Clone,Copy,Debug,PartialEq,Default)]
-pub enum SubMBType {
-    P8x8,
-    P8x4,
-    P4x8,
-    P4x4,
-    #[default]
-    Direct8x8,
-    B8x8(BMode),
-    B8x4(BMode),
-    B4x8(BMode),
-    B4x4(BMode),
-}
-
-impl SubMBType {
-    pub fn num_parts(self) -> usize {
-        match self {
-            SubMBType::P8x8 | SubMBType::Direct8x8 | SubMBType::B8x8(_) => 1,
-            SubMBType::P4x4 | SubMBType::B4x4(_) => 4,
-            _ => 2,
-        }
-    }
-    pub fn size(self) -> (usize, usize) {
-        match self {
-            SubMBType::P8x8 | SubMBType::Direct8x8 | SubMBType::B8x8(_) => (8, 8),
-            SubMBType::P8x4 | SubMBType::B8x4(_) => (8, 4),
-            SubMBType::P4x8 | SubMBType::B4x8(_) => (4, 8),
-            SubMBType::P4x4 | SubMBType::B4x4(_) => (4, 4),
-        }
-    }
-    pub fn is_l0(self) -> bool {
-        match self {
-            SubMBType::B8x8(mode) | SubMBType::B8x4(mode) |
-            SubMBType::B4x8(mode) | SubMBType::B4x4(mode) => {
-                mode == BMode::L0
-            },
-            _ => true,
-        }
-    }
-    pub fn is_l1(self) -> bool {
-        match self {
-            SubMBType::B8x8(mode) | SubMBType::B8x4(mode) |
-            SubMBType::B4x8(mode) | SubMBType::B4x4(mode) => {
-                mode == BMode::L1
-            },
-            _ => false,
-        }
-    }
-}
-
-#[repr(u8)]
-#[derive(Clone,Copy,Debug,PartialEq,Default)]
-pub enum CompactMBType {
-    Intra4x4,
-    Intra8x8,
-    Intra16x16,
-    PCM,
-
-    P16x16,
-    P16x8,
-    P8x16,
-    P8x8,
-    P8x8Ref0,
-    PSkip,
-
-    Direct,
-    B16x16,
-    B16x8,
-    B8x16,
-    B8x8,
-    BSkip,
-
-    #[default]
-    None,
-}
-
-impl CompactMBType {
-    pub fn is_intra(self) -> bool {
-        matches!(self, CompactMBType::Intra4x4 | CompactMBType::Intra8x8 | CompactMBType::Intra16x16)
-    }
-    pub fn is_intra16orpcm(self) -> bool {
-        matches!(self, CompactMBType::Intra16x16 | CompactMBType::PCM)
-    }
-    pub fn is_skip(self) -> bool {
-        matches!(self, CompactMBType::PSkip | CompactMBType::BSkip)
-    }
-    pub fn is_direct(self) -> bool {
-        matches!(self, CompactMBType::BSkip | CompactMBType::Direct | CompactMBType::None)
-    }
-    pub fn is_inter(self) -> bool {
-        !self.is_intra() && !self.is_skip() && self != CompactMBType::PCM
-    }
-    pub fn is_16x16_ref(self) -> bool {
-        matches!(self,
-            CompactMBType::Intra4x4 |
-            CompactMBType::Intra8x8 |
-            CompactMBType::Intra16x16 |
-            CompactMBType::PCM |
-            CompactMBType::P16x16 |
-            CompactMBType::B16x16)
-    }
-}
-
-impl From<MBType> for CompactMBType {
-    fn from(mbtype: MBType) -> Self {
-        match mbtype {
-            MBType::Intra4x4 => CompactMBType::Intra4x4,
-            MBType::Intra8x8 => CompactMBType::Intra8x8,
-            MBType::Intra16x16(_, _, _) => CompactMBType::Intra16x16,
-            MBType::PCM => CompactMBType::PCM,
-            MBType::P16x16 => CompactMBType::P16x16,
-            MBType::P16x8 => CompactMBType::P16x8,
-            MBType::P8x16 => CompactMBType::P8x16,
-            MBType::P8x8 => CompactMBType::P8x8,
-            MBType::P8x8Ref0 => CompactMBType::P8x8Ref0,
-            MBType::PSkip => CompactMBType::PSkip,
-            MBType::Direct => CompactMBType::Direct,
-            MBType::B16x16(_) => CompactMBType::B16x16,
-            MBType::B16x8(_, _) => CompactMBType::B16x8,
-            MBType::B8x16(_, _) => CompactMBType::B8x16,
-            MBType::B8x8 => CompactMBType::B8x8,
-            MBType::BSkip => CompactMBType::BSkip,
-        }
-    }
-}
-
-#[repr(u8)]
-#[derive(Clone,Copy,Debug,PartialEq,Default)]
-pub enum IntraPredMode {
-    Vertical,
-    Horizontal,
-    DC,
-    DiagDownLeft,
-    DiagDownRight,
-    VerRight,
-    HorDown,
-    VerLeft,
-    HorUp,
-    #[default]
-    None,
-}
-
-impl IntraPredMode {
-    pub fn is_none(self) -> bool { self == IntraPredMode::None }
-    pub fn into_pred_idx(self) -> i8 {
-        if !self.is_none() {
-            self as u8 as i8
-        } else {
-            -1
-        }
-    }
-}
-
-impl From<u8> for IntraPredMode {
-    fn from(val: u8) -> Self {
-        match val {
-            0 => IntraPredMode::Vertical,
-            1 => IntraPredMode::Horizontal,
-            2 => IntraPredMode::DC,
-            3 => IntraPredMode::DiagDownLeft,
-            4 => IntraPredMode::DiagDownRight,
-            5 => IntraPredMode::VerRight,
-            6 => IntraPredMode::HorDown,
-            7 => IntraPredMode::VerLeft,
-            8 => IntraPredMode::HorUp,
-            _ => IntraPredMode::None,
-        }
-    }
-}
-
-impl From<IntraPredMode> for u8 {
-    fn from(val: IntraPredMode) -> Self {
-        match val {
-            IntraPredMode::Vertical      => 0,
-            IntraPredMode::Horizontal    => 1,
-            IntraPredMode::DC            => 2,
-            IntraPredMode::DiagDownLeft  => 3,
-            IntraPredMode::DiagDownRight => 4,
-            IntraPredMode::VerRight      => 5,
-            IntraPredMode::HorDown       => 6,
-            IntraPredMode::VerLeft       => 7,
-            IntraPredMode::HorUp         => 8,
-            _ => 9,
-        }
-    }
-}
-
-pub const MISSING_POC: u16 = 0xFFFF;
-
-#[derive(Clone,Copy,Debug)]
-pub struct PicRef {
-    ref_idx: u8
-}
-
-pub const MISSING_REF: PicRef = PicRef { ref_idx: 0xFF };
-pub const INVALID_REF: PicRef = PicRef { ref_idx: 0xFE };
-pub const ZERO_REF: PicRef = PicRef { ref_idx: 0 };
-const DIRECT_FLAG: u8 = 0x40;
-
-impl PicRef {
-    pub fn new(ref_idx: u8) -> Self {
-        Self { ref_idx }
-    }
-    pub fn not_avail(self) -> bool {
-        self == MISSING_REF || self == INVALID_REF
-    }
-    pub fn index(self) -> usize { (self.ref_idx & !DIRECT_FLAG) as usize }
-    pub fn is_direct(self) -> bool { (self.ref_idx & DIRECT_FLAG) != 0 }
-    pub fn set_direct(&mut self) { self.ref_idx |= DIRECT_FLAG; }
-    fn min_pos(self, other: Self) -> Self {
-        match (self.not_avail(), other.not_avail()) {
-            (true,  true)   => self,
-            (false, true)   => self,
-            (true,  false)  => other,
-            (false, false)  => PicRef::new((self.ref_idx & !DIRECT_FLAG).min(other.ref_idx & !DIRECT_FLAG)),
-        }
-    }
-}
-
-impl Default for PicRef {
-    fn default() -> Self { MISSING_REF }
-}
-
-impl PartialEq for PicRef {
-    fn eq(&self, other: &Self) -> bool {
-        (self.ref_idx | DIRECT_FLAG) == (other.ref_idx | DIRECT_FLAG)
-    }
-}
-
-impl std::fmt::Display for PicRef {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        if *self == MISSING_REF {
-            write!(f, "-1")
-        } else if *self == INVALID_REF {
-            write!(f, "-2")
-        } else {
-            write!(f, "{}", self.ref_idx & !DIRECT_FLAG)
-        }
-    }
-}
-
-#[derive(Clone,Copy,Default)]
-pub struct MBData {
-    pub mb_type:        CompactMBType,
-    pub cbp:            u8,
-    pub coded_flags:    u32,
-    pub cmode:          u8,
-    pub qp_y:           u8,
-    pub qp_u:           u8,
-    pub qp_v:           u8,
-    pub transform_8x8:  bool,
-}
-
-pub fn blk4_to_blk8(blk4: usize) -> usize {
-    /*const MAP: [usize; 16] = [ 0, 0, 1, 1, 0, 0, 1, 1, 2, 2, 3, 3, 2, 2, 3, 3 ];
-    MAP[blk4 & 0xF]*/
-    ((blk4 & 2) >> 1) | ((blk4 & 8) >> 2)
-}
-
-#[derive(Clone,Copy)]
-pub struct Blk8Data {
-    pub ref_idx:    [PicRef; 2],
-    pub ncoded_c:   [u8; 2],
-}
-
-impl Default for Blk8Data {
-    fn default() -> Self {
-        Self {
-            ref_idx:        [MISSING_REF; 2],
-            ncoded_c:       [0; 2],
-        }
-    }
-}
-
-#[derive(Clone,Copy,Default)]
-pub struct Blk4Data {
-    pub ncoded:     u8,
-    pub ipred:      IntraPredMode,
-    pub mv:         [MV; 2],
-    pub mvd:        [MV; 2],
-}
-
 pub struct SliceState {
     pub mb_x:           usize,
     pub mb_y:           usize,
@@ -435,12 +51,6 @@ pub struct SliceState {
 
 const BLK4_TO_D8: [usize; 16] = [ 0, 0, 3, 3, 0, 0, 3, 3, 12, 12, 15, 15, 12, 12, 15, 15 ];
 
-#[repr(align(8))]
-#[derive(Default)]
-struct MVCache {
-    data:   [[MV; 2]; 25]
-}
-
 impl SliceState {
     pub fn new() -> Self {
         Self {
@@ -954,28 +564,3 @@ impl SliceState {
         }
     }
 }
-
-#[cfg(not(target_arch="x86_64"))]
-fn mvdiff4(mv1: &[MV; 2], mv2: &[MV; 2]) -> bool {
-    let mvd0 = mv1[0] - mv2[0];
-    let mvd1 = mv1[1] - mv2[1];
-    (mvd0.x.abs() >= 4) || (mvd0.y.abs() >= 4) || (mvd1.x.abs() >= 4) || (mvd1.y.abs() >= 4)
-}
-
-#[cfg(target_arch="x86_64")]
-fn mvdiff4(mv1: &[MV; 2], mv2: &[MV; 2]) -> bool {
-    unsafe {
-        let mut flag = false;
-        let ptr = std::mem::transmute::<*const MV, *const u64>(mv1.as_ptr());
-        let mut m0 = *ptr;
-        let ptr = std::mem::transmute::<*const MV, *const u64>(mv2.as_ptr());
-        let mut m1 = *ptr;
-        for _ in 0..4 {
-            let tmp = m0.wrapping_sub(m1) as u16;
-            flag |= tmp.wrapping_add(3) > 6;
-            m0 >>= 16;
-            m1 >>= 16;
-        }
-        flag
-    }
-}
diff --git a/nihav-itu/src/codecs/h264/common_types.rs b/nihav-itu/src/codecs/h264/common_types.rs
new file mode 100644 (file)
index 0000000..ef21430
--- /dev/null
@@ -0,0 +1,417 @@
+use nihav_codec_support::codecs::MV;
+
+#[repr(u8)]
+#[derive(Clone,Copy,Debug,PartialEq)]
+pub enum BMode {
+    L0,
+    L1,
+    Bi,
+}
+
+#[derive(Clone,Copy,Debug,PartialEq,Default)]
+pub enum MBType {
+    #[default]
+    Intra4x4,
+    Intra8x8,
+    Intra16x16(u8, u8, u8),
+    PCM,
+
+    P16x16,
+    P16x8,
+    P8x16,
+    P8x8,
+    P8x8Ref0,
+    PSkip,
+
+    Direct,
+    B16x16(BMode),
+    B16x8(BMode, BMode),
+    B8x16(BMode, BMode),
+    B8x8,
+    BSkip,
+}
+
+impl MBType {
+    pub fn is_intra(self) -> bool {
+        matches!(self, MBType::Intra4x4 | MBType::Intra8x8 | MBType::Intra16x16(_, _, _) | MBType::PCM)
+    }
+    pub fn is_intra16x16(self) -> bool {
+        matches!(self, MBType::Intra16x16(_, _, _))
+    }
+    pub fn is_skip(self) -> bool {
+        matches!(self, MBType::PSkip | MBType::BSkip)
+    }
+    pub fn is_4x4(self) -> bool { self.num_parts() == 4 }
+    pub fn is_l0(self, part: usize) -> bool {
+        match self {
+            MBType::B16x16(mode) => mode == BMode::L0,
+            MBType::B16x8(mode0, mode1) | MBType::B8x16(mode0, mode1) => {
+                if part == 0 {
+                    mode0 == BMode::L0
+                } else {
+                    mode1 == BMode::L0
+                }
+            },
+            MBType::Direct | MBType::BSkip => false,
+            _ => true,
+        }
+    }
+    pub fn is_l1(self, part: usize) -> bool {
+        match self {
+            MBType::B16x16(mode) => mode == BMode::L1,
+            MBType::B16x8(mode0, mode1) | MBType::B8x16(mode0, mode1) => {
+                if part == 0 {
+                    mode0 == BMode::L1
+                } else {
+                    mode1 == BMode::L1
+                }
+            },
+            _ => false,
+        }
+    }
+    pub fn num_parts(self) -> usize {
+        match self {
+            MBType::Intra4x4 | MBType::Intra8x8 | MBType::Intra16x16(_, _, _) | MBType::PCM |
+            MBType::PSkip |
+            MBType::Direct | MBType::BSkip
+                => 1,
+            MBType::P16x16 |
+            MBType::B16x16(_)
+                => 1,
+            MBType::P16x8 | MBType::P8x16 |
+            MBType::B16x8(_, _) | MBType::B8x16(_, _)
+                => 2,
+            _ => 4,
+        }
+    }
+    pub fn size(self) -> (usize, usize) {
+        match self {
+            MBType::Intra4x4 |
+            MBType::Intra8x8 |
+            MBType::Intra16x16(_, _, _) |
+            MBType::PCM |
+            MBType::P16x16 |
+            MBType::PSkip |
+            MBType::Direct |
+            MBType::B16x16(_) |
+            MBType::BSkip
+                => (16, 16),
+            MBType::P16x8 | MBType::B16x8(_, _) => (16, 8),
+            MBType::P8x16 | MBType::B8x16(_, _) => (8, 16),
+            _ => (8, 8),
+        }
+    }
+}
+
+#[derive(Clone,Copy,Debug,PartialEq,Default)]
+pub enum SubMBType {
+    P8x8,
+    P8x4,
+    P4x8,
+    P4x4,
+    #[default]
+    Direct8x8,
+    B8x8(BMode),
+    B8x4(BMode),
+    B4x8(BMode),
+    B4x4(BMode),
+}
+
+impl SubMBType {
+    pub fn num_parts(self) -> usize {
+        match self {
+            SubMBType::P8x8 | SubMBType::Direct8x8 | SubMBType::B8x8(_) => 1,
+            SubMBType::P4x4 | SubMBType::B4x4(_) => 4,
+            _ => 2,
+        }
+    }
+    pub fn size(self) -> (usize, usize) {
+        match self {
+            SubMBType::P8x8 | SubMBType::Direct8x8 | SubMBType::B8x8(_) => (8, 8),
+            SubMBType::P8x4 | SubMBType::B8x4(_) => (8, 4),
+            SubMBType::P4x8 | SubMBType::B4x8(_) => (4, 8),
+            SubMBType::P4x4 | SubMBType::B4x4(_) => (4, 4),
+        }
+    }
+    pub fn is_l0(self) -> bool {
+        match self {
+            SubMBType::B8x8(mode) | SubMBType::B8x4(mode) |
+            SubMBType::B4x8(mode) | SubMBType::B4x4(mode) => {
+                mode == BMode::L0
+            },
+            _ => true,
+        }
+    }
+    pub fn is_l1(self) -> bool {
+        match self {
+            SubMBType::B8x8(mode) | SubMBType::B8x4(mode) |
+            SubMBType::B4x8(mode) | SubMBType::B4x4(mode) => {
+                mode == BMode::L1
+            },
+            _ => false,
+        }
+    }
+}
+
+#[repr(u8)]
+#[derive(Clone,Copy,Debug,PartialEq,Default)]
+pub enum CompactMBType {
+    Intra4x4,
+    Intra8x8,
+    Intra16x16,
+    PCM,
+
+    P16x16,
+    P16x8,
+    P8x16,
+    P8x8,
+    P8x8Ref0,
+    PSkip,
+
+    Direct,
+    B16x16,
+    B16x8,
+    B8x16,
+    B8x8,
+    BSkip,
+
+    #[default]
+    None,
+}
+
+impl CompactMBType {
+    pub fn is_intra(self) -> bool {
+        matches!(self, CompactMBType::Intra4x4 | CompactMBType::Intra8x8 | CompactMBType::Intra16x16)
+    }
+    pub fn is_intra16orpcm(self) -> bool {
+        matches!(self, CompactMBType::Intra16x16 | CompactMBType::PCM)
+    }
+    pub fn is_skip(self) -> bool {
+        matches!(self, CompactMBType::PSkip | CompactMBType::BSkip)
+    }
+    pub fn is_direct(self) -> bool {
+        matches!(self, CompactMBType::BSkip | CompactMBType::Direct | CompactMBType::None)
+    }
+    pub fn is_inter(self) -> bool {
+        !self.is_intra() && !self.is_skip() && self != CompactMBType::PCM
+    }
+    pub fn is_16x16_ref(self) -> bool {
+        matches!(self,
+            CompactMBType::Intra4x4 |
+            CompactMBType::Intra8x8 |
+            CompactMBType::Intra16x16 |
+            CompactMBType::PCM |
+            CompactMBType::P16x16 |
+            CompactMBType::B16x16)
+    }
+}
+
+impl From<MBType> for CompactMBType {
+    fn from(mbtype: MBType) -> Self {
+        match mbtype {
+            MBType::Intra4x4 => CompactMBType::Intra4x4,
+            MBType::Intra8x8 => CompactMBType::Intra8x8,
+            MBType::Intra16x16(_, _, _) => CompactMBType::Intra16x16,
+            MBType::PCM => CompactMBType::PCM,
+            MBType::P16x16 => CompactMBType::P16x16,
+            MBType::P16x8 => CompactMBType::P16x8,
+            MBType::P8x16 => CompactMBType::P8x16,
+            MBType::P8x8 => CompactMBType::P8x8,
+            MBType::P8x8Ref0 => CompactMBType::P8x8Ref0,
+            MBType::PSkip => CompactMBType::PSkip,
+            MBType::Direct => CompactMBType::Direct,
+            MBType::B16x16(_) => CompactMBType::B16x16,
+            MBType::B16x8(_, _) => CompactMBType::B16x8,
+            MBType::B8x16(_, _) => CompactMBType::B8x16,
+            MBType::B8x8 => CompactMBType::B8x8,
+            MBType::BSkip => CompactMBType::BSkip,
+        }
+    }
+}
+
+#[repr(u8)]
+#[derive(Clone,Copy,Debug,PartialEq,Default)]
+pub enum IntraPredMode {
+    Vertical,
+    Horizontal,
+    DC,
+    DiagDownLeft,
+    DiagDownRight,
+    VerRight,
+    HorDown,
+    VerLeft,
+    HorUp,
+    #[default]
+    None,
+}
+
+impl IntraPredMode {
+    pub fn is_none(self) -> bool { self == IntraPredMode::None }
+    pub fn into_pred_idx(self) -> i8 {
+        if !self.is_none() {
+            self as u8 as i8
+        } else {
+            -1
+        }
+    }
+}
+
+impl From<u8> for IntraPredMode {
+    fn from(val: u8) -> Self {
+        match val {
+            0 => IntraPredMode::Vertical,
+            1 => IntraPredMode::Horizontal,
+            2 => IntraPredMode::DC,
+            3 => IntraPredMode::DiagDownLeft,
+            4 => IntraPredMode::DiagDownRight,
+            5 => IntraPredMode::VerRight,
+            6 => IntraPredMode::HorDown,
+            7 => IntraPredMode::VerLeft,
+            8 => IntraPredMode::HorUp,
+            _ => IntraPredMode::None,
+        }
+    }
+}
+
+impl From<IntraPredMode> for u8 {
+    fn from(val: IntraPredMode) -> Self {
+        match val {
+            IntraPredMode::Vertical      => 0,
+            IntraPredMode::Horizontal    => 1,
+            IntraPredMode::DC            => 2,
+            IntraPredMode::DiagDownLeft  => 3,
+            IntraPredMode::DiagDownRight => 4,
+            IntraPredMode::VerRight      => 5,
+            IntraPredMode::HorDown       => 6,
+            IntraPredMode::VerLeft       => 7,
+            IntraPredMode::HorUp         => 8,
+            _ => 9,
+        }
+    }
+}
+
+pub const MISSING_POC: u16 = 0xFFFF;
+
+#[derive(Clone,Copy,Debug)]
+pub struct PicRef {
+    ref_idx: u8
+}
+
+pub const MISSING_REF: PicRef = PicRef { ref_idx: 0xFF };
+pub const INVALID_REF: PicRef = PicRef { ref_idx: 0xFE };
+pub const ZERO_REF: PicRef = PicRef { ref_idx: 0 };
+const DIRECT_FLAG: u8 = 0x40;
+
+impl PicRef {
+    pub fn new(ref_idx: u8) -> Self {
+        Self { ref_idx }
+    }
+    pub fn not_avail(self) -> bool {
+        self == MISSING_REF || self == INVALID_REF
+    }
+    pub fn index(self) -> usize { (self.ref_idx & !DIRECT_FLAG) as usize }
+    pub fn is_direct(self) -> bool { (self.ref_idx & DIRECT_FLAG) != 0 }
+    pub fn set_direct(&mut self) { self.ref_idx |= DIRECT_FLAG; }
+    pub fn min_pos(self, other: Self) -> Self {
+        match (self.not_avail(), other.not_avail()) {
+            (true,  true)   => self,
+            (false, true)   => self,
+            (true,  false)  => other,
+            (false, false)  => PicRef::new((self.ref_idx & !DIRECT_FLAG).min(other.ref_idx & !DIRECT_FLAG)),
+        }
+    }
+}
+
+impl Default for PicRef {
+    fn default() -> Self { MISSING_REF }
+}
+
+impl PartialEq for PicRef {
+    fn eq(&self, other: &Self) -> bool {
+        (self.ref_idx | DIRECT_FLAG) == (other.ref_idx | DIRECT_FLAG)
+    }
+}
+
+impl std::fmt::Display for PicRef {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        if *self == MISSING_REF {
+            write!(f, "-1")
+        } else if *self == INVALID_REF {
+            write!(f, "-2")
+        } else {
+            write!(f, "{}", self.ref_idx & !DIRECT_FLAG)
+        }
+    }
+}
+
+#[derive(Clone,Copy,Default)]
+pub struct MBData {
+    pub mb_type:        CompactMBType,
+    pub cbp:            u8,
+    pub coded_flags:    u32,
+    pub cmode:          u8,
+    pub qp_y:           u8,
+    pub qp_u:           u8,
+    pub qp_v:           u8,
+    pub transform_8x8:  bool,
+}
+
+pub fn blk4_to_blk8(blk4: usize) -> usize {
+    /*const MAP: [usize; 16] = [ 0, 0, 1, 1, 0, 0, 1, 1, 2, 2, 3, 3, 2, 2, 3, 3 ];
+    MAP[blk4 & 0xF]*/
+    ((blk4 & 2) >> 1) | ((blk4 & 8) >> 2)
+}
+
+#[derive(Clone,Copy)]
+pub struct Blk8Data {
+    pub ref_idx:    [PicRef; 2],
+    pub ncoded_c:   [u8; 2],
+}
+
+impl Default for Blk8Data {
+    fn default() -> Self {
+        Self {
+            ref_idx:        [MISSING_REF; 2],
+            ncoded_c:       [0; 2],
+        }
+    }
+}
+
+#[derive(Clone,Copy,Default)]
+pub struct Blk4Data {
+    pub ncoded:     u8,
+    pub ipred:      IntraPredMode,
+    pub mv:         [MV; 2],
+    pub mvd:        [MV; 2],
+}
+
+#[repr(align(8))]
+#[derive(Default)]
+pub struct MVCache {
+    pub data:   [[MV; 2]; 25]
+}
+
+#[cfg(not(target_arch="x86_64"))]
+pub fn mvdiff4(mv1: &[MV; 2], mv2: &[MV; 2]) -> bool {
+    let mvd0 = mv1[0] - mv2[0];
+    let mvd1 = mv1[1] - mv2[1];
+    (mvd0.x.abs() >= 4) || (mvd0.y.abs() >= 4) || (mvd1.x.abs() >= 4) || (mvd1.y.abs() >= 4)
+}
+
+#[cfg(target_arch="x86_64")]
+pub fn mvdiff4(mv1: &[MV; 2], mv2: &[MV; 2]) -> bool {
+    unsafe {
+        let mut flag = false;
+        let ptr = std::mem::transmute::<*const MV, *const u64>(mv1.as_ptr());
+        let mut m0 = *ptr;
+        let ptr = std::mem::transmute::<*const MV, *const u64>(mv2.as_ptr());
+        let mut m1 = *ptr;
+        for _ in 0..4 {
+            let tmp = m0.wrapping_sub(m1) as u16;
+            flag |= tmp.wrapping_add(3) > 6;
+            m0 >>= 16;
+            m1 >>= 16;
+        }
+        flag
+    }
+}
index e3349973490490947f94ca47a44c3f544ecd33e6..52e8d0e4f2b02cef2376621663d08b1fc9b96266 100644 (file)
@@ -12,38 +12,16 @@ use nihav_core::io::bitreader::*;
 use nihav_core::io::intcode::*;
 use nihav_codec_support::codecs::{MV, ZERO_MV};
 
-pub type Shareable<T> = Arc<RwLock<T>>;
-
-mod types;
-pub use types::*;
-mod pic_ref;
-pub use pic_ref::*;
-#[allow(clippy::identity_op)]
-#[allow(clippy::erasing_op)]
-#[allow(clippy::many_single_char_names)]
-#[allow(clippy::range_plus_one)]
-mod dsp;
-use dsp::*;
-mod cabac;
-use cabac::*;
+mod baseline;
 mod cabac_coder;
-use cabac_coder::*;
-mod cavlc;
-use cavlc::*;
-mod loopfilter;
-use loopfilter::*;
-mod mb_recon;
-use mb_recon::*;
+mod common_types;
+use common_types::*;
+pub use baseline::{get_decoder, get_decoder_mt};
 mod sets;
-use sets::*;
 mod slice;
 use slice::*;
 
-mod decoder_st;
-pub use decoder_st::*;
-mod dispatch;
-mod decoder_mt;
-pub use decoder_mt::*;
+pub type Shareable<T> = Arc<RwLock<T>>;
 
 trait ReadUE {
     fn read_ue(&mut self) -> DecoderResult<u32>;
@@ -82,25 +60,6 @@ impl<'a> ReadUE for BitReader<'a> {
     }
 }
 
-#[derive(Clone,Copy)]
-pub struct Coeff8x8 {
-    pub coeffs:     [i16; 64],
-}
-
-impl Coeff8x8 {
-    fn clear(&mut self) {
-        self.coeffs = [0; 64];
-    }
-}
-
-impl Default for Coeff8x8 {
-    fn default() -> Self {
-        Self {
-            coeffs: [0; 64],
-        }
-    }
-}
-
 #[derive(Clone,Copy,Default)]
 pub struct CurrentMBInfo {
     pub mb_type:        MBType,
@@ -149,6 +108,25 @@ impl CurrentMBInfo {
     }
 }
 
+#[derive(Clone,Copy)]
+pub struct Coeff8x8 {
+    pub coeffs:     [i16; 64],
+}
+
+impl Coeff8x8 {
+    fn clear(&mut self) {
+        self.coeffs = [0; 64];
+    }
+}
+
+impl Default for Coeff8x8 {
+    fn default() -> Self {
+        Self {
+            coeffs: [0; 64],
+        }
+    }
+}
+
 fn get_long_term_id(is_idr: bool, slice_hdr: &SliceHeader) -> Option<usize> {
     if is_idr && !slice_hdr.long_term_reference {
         None