1 use nihav_core::codecs::*;
2 use nihav_core::io::byteio::*;
3 use nihav_codec_support::codecs::HAMShuffler;
5 const RGB555_FORMAT: NAPixelFormaton = NAPixelFormaton {
6 model: ColorModel::RGB(RGBSubmodel::RGB), components: 3,
8 Some(NAPixelChromaton{ h_ss: 0, v_ss: 0, packed: true, depth: 5, shift: 10, comp_offs: 0, next_elem: 2 }),
9 Some(NAPixelChromaton{ h_ss: 0, v_ss: 0, packed: true, depth: 5, shift: 5, comp_offs: 0, next_elem: 2 }),
10 Some(NAPixelChromaton{ h_ss: 0, v_ss: 0, packed: true, depth: 5, shift: 0, comp_offs: 0, next_elem: 2 }),
12 elem_size: 2, be: false, alpha: false, palette: false };
15 struct Video1Decoder {
17 hams: HAMShuffler<u8>,
18 hams16: HAMShuffler<u16>,
28 fn decode_frame(&self, br: &mut ByteReader, frm: &mut NASimpleVideoFrame<u8>) -> DecoderResult<FrameType> {
29 let off = frm.offset[0];
30 let stride = frm.stride[0];
31 let mut skip_count = 0;
32 let blk_w = (self.width + 3) >> 2;
33 let blk_h = (self.height + 3) >> 2;
36 while cur_x < blk_w && cur_y < blk_h {
37 let op = br.read_u16le()?;
41 br.read_buf(&mut clr)?;
42 let mut flags = !op as usize;
43 let cur_off = off + cur_x * 4 + cur_y * 4 * stride;
46 frm.data[cur_off + i + j * stride] = clr[flags & 1];
51 } else if op < 0x8400 {
52 let cur_off = off + cur_x * 4 + cur_y * 4 * stride;
56 frm.data[cur_off + i + j * stride] = clr;
60 } else if op < 0x8800 {
61 advance = (op & 0x3FF) as usize;
62 validate!(advance > 0);
63 skip_count += advance;
66 br.read_buf(&mut clr)?;
67 let mut flags = !op as usize;
68 let cur_off = off + cur_x * 4 + cur_y * 4 * stride;
71 frm.data[cur_off + i + j * stride] = clr[(i >> 1) * 2 + (j >> 1) * 4 + (flags & 1)];
78 while cur_x >= blk_w {
83 validate!(cur_x == 0 && cur_y == blk_h);
86 } else if skip_count < blk_w * blk_h {
92 fn decode_frame16(&self, br: &mut ByteReader, frm: &mut NASimpleVideoFrame<u16>) -> DecoderResult<FrameType> {
93 let off = frm.offset[0];
94 let stride = frm.stride[0];
95 let mut skip_count = 0;
96 let blk_w = (self.width + 3) >> 2;
97 let blk_h = (self.height + 3) >> 2;
100 while cur_x < blk_w && cur_y < blk_h {
101 let op = br.read_u16le()?;
103 if (op & 0x8000) == 0 {
104 let mut clr = [0; 8];
105 clr[0] = br.read_u16le()?;
106 clr[1] = br.read_u16le()?;
107 let mut flags = !op as usize;
108 let cur_off = off + cur_x * 4 + cur_y * 4 * stride;
109 if (clr[0] & 0x8000) == 0 {
112 frm.data[cur_off + i + j * stride] = clr[flags & 1];
117 clr[2] = br.read_u16le()?;
118 clr[3] = br.read_u16le()?;
119 clr[4] = br.read_u16le()?;
120 clr[5] = br.read_u16le()?;
121 clr[6] = br.read_u16le()?;
122 clr[7] = br.read_u16le()?;
125 frm.data[cur_off + i + j * stride] = clr[(i >> 1) * 2 + (j >> 1) * 4 + (flags & 1)];
131 } else if (op & 0xFC00) == 0x8400 {
132 advance = (op & 0x3FF) as usize;
133 validate!(advance > 0);
134 skip_count += advance;
136 let cur_off = off + cur_x * 4 + cur_y * 4 * stride;
137 let clr = op & 0x7FFF;
140 frm.data[cur_off + i + j * stride] = clr;
146 while cur_x >= blk_w {
151 validate!((cur_x == 0 || cur_x == 1) && cur_y == blk_h);
154 } else if skip_count < blk_w * blk_h {
162 impl NADecoder for Video1Decoder {
163 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
164 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
165 self.is_16bit = !vinfo.get_format().palette;
166 let fmt = if !self.is_16bit { PAL8_FORMAT } else { RGB555_FORMAT };
167 self.width = vinfo.get_width();
168 self.height = vinfo.get_height();
169 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(self.width, self.height, true, fmt));
170 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
174 Err(DecoderError::InvalidData)
177 #[allow(clippy::identity_op)]
178 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
179 let src = pkt.get_buffer();
180 validate!(src.len() >= 2);
181 let mut mr = MemoryReader::new_read(src.as_slice());
182 let mut br = ByteReader::new(&mut mr);
187 let bufret = self.hams.clone_ref();
189 if let Some(bbuf) = bufret {
192 let bufinfo = alloc_video_buffer(self.info.get_properties().get_video_info().unwrap(), 2)?;
193 buf = bufinfo.get_vbuf().unwrap();
194 self.hams.add_frame(buf);
195 buf = self.hams.get_output_frame().unwrap();
197 let mut frm = NASimpleVideoFrame::from_video_buf(&mut buf).unwrap();
198 ftype = self.decode_frame(&mut br, &mut frm)?;
199 let paloff = frm.offset[1];
200 let dpal = &mut frm.data[paloff..];
201 let mut found_pal = false;
202 for sd in pkt.side_data.iter() {
204 NASideData::Palette(_, ref pal) => {
205 for (dst, src) in dpal.chunks_mut(3).zip(pal.chunks(4)) {
218 dpal[i * 3 + 0] = i as u8;
219 dpal[i * 3 + 1] = i as u8;
220 dpal[i * 3 + 2] = i as u8;
223 buftype = NABufferType::Video(buf);
225 let bufret = self.hams16.clone_ref();
227 if let Some(bbuf) = bufret {
230 let bufinfo = alloc_video_buffer(self.info.get_properties().get_video_info().unwrap(), 2)?;
231 buf = bufinfo.get_vbuf16().unwrap();
232 self.hams16.add_frame(buf);
233 buf = self.hams16.get_output_frame().unwrap();
235 let mut frm = NASimpleVideoFrame::from_video_buf(&mut buf).unwrap();
236 ftype = self.decode_frame16(&mut br, &mut frm)?;
237 buftype = NABufferType::Video16(buf);
240 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), buftype);
241 frm.set_keyframe(ftype == FrameType::I);
242 frm.set_frame_type(ftype);
245 fn flush(&mut self) {
251 impl NAOptionHandler for Video1Decoder {
252 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
253 fn set_options(&mut self, _options: &[NAOption]) { }
254 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
257 pub fn get_decoder() -> Box<dyn NADecoder + Send> {
258 Box::new(Video1Decoder::new())
263 use nihav_core::codecs::RegisteredDecoders;
264 use nihav_core::demuxers::RegisteredDemuxers;
265 use nihav_codec_support::test::dec_video::*;
266 use crate::ms_register_all_codecs;
267 use nihav_commonfmt::generic_register_all_demuxers;
269 fn test_ms_video1_8bit() {
270 let mut dmx_reg = RegisteredDemuxers::new();
271 generic_register_all_demuxers(&mut dmx_reg);
272 let mut dec_reg = RegisteredDecoders::new();
273 ms_register_all_codecs(&mut dec_reg);
275 test_decoding("avi", "msvideo1", "assets/MS/toon.avi", Some(66), &dmx_reg, &dec_reg,
276 ExpectedTestResult::MD5([0x0c26ec42, 0xb75bfea7, 0x1e6342ae, 0xb14dcfa3]));
279 fn test_ms_video1_16bit() {
280 let mut dmx_reg = RegisteredDemuxers::new();
281 generic_register_all_demuxers(&mut dmx_reg);
282 let mut dec_reg = RegisteredDecoders::new();
283 ms_register_all_codecs(&mut dec_reg);
285 test_decoding("avi", "msvideo1", "assets/MS/clock-cram16.avi", None, &dmx_reg, &dec_reg,
286 ExpectedTestResult::MD5([0x03381fa4, 0x5b294fec, 0xb97a7575, 0xa1a3ffe9]));