1 use nihav_core::codecs::*;
2 use nihav_core::io::byteio::*;
3 use nihav_codec_support::codecs::HAMShuffler;
6 lastframe: Option<NAVideoBufferRef<u16>>,
10 fn clear(&mut self) { self.lastframe = None; }
11 fn add_frame(&mut self, buf: NAVideoBufferRef<u16>) {
12 self.lastframe = Some(buf);
14 fn clone_ref(&mut self) -> Option<NAVideoBufferRef<u16>> {
15 if let Some(ref mut frm) = self.lastframe {
16 let newfrm = frm.copy_buffer();
17 *frm = newfrm.clone().into_ref();
18 Some(newfrm.into_ref())
23 fn get_output_frame(&mut self) -> Option<NAVideoBufferRef<u16>> {
24 match self.lastframe {
25 Some(ref frm) => Some(frm.clone()),
31 impl Default for HAMShuffler16 {
32 fn default() -> Self { Self { lastframe: None } }
35 const RGB555_FORMAT: NAPixelFormaton = NAPixelFormaton {
36 model: ColorModel::RGB(RGBSubmodel::RGB), components: 3,
38 Some(NAPixelChromaton{ h_ss: 0, v_ss: 0, packed: true, depth: 5, shift: 10, comp_offs: 0, next_elem: 2 }),
39 Some(NAPixelChromaton{ h_ss: 0, v_ss: 0, packed: true, depth: 5, shift: 5, comp_offs: 0, next_elem: 2 }),
40 Some(NAPixelChromaton{ h_ss: 0, v_ss: 0, packed: true, depth: 5, shift: 0, comp_offs: 0, next_elem: 2 }),
42 elem_size: 2, be: false, alpha: false, palette: false };
45 struct Video1Decoder {
48 hams16: HAMShuffler16,
58 fn decode_frame(&self, br: &mut ByteReader, frm: &mut NASimpleVideoFrame<u8>) -> DecoderResult<FrameType> {
59 let off = frm.offset[0];
60 let stride = frm.stride[0];
61 let mut skip_count = 0;
62 let blk_w = (self.width + 3) >> 2;
63 let blk_h = (self.height + 3) >> 2;
66 while cur_x < blk_w && cur_y < blk_h {
67 let op = br.read_u16le()?;
71 br.read_buf(&mut clr)?;
72 let mut flags = !op as usize;
73 let cur_off = off + cur_x * 4 + cur_y * 4 * stride;
76 frm.data[cur_off + i + j * stride] = clr[flags & 1];
81 } else if op < 0x8400 {
82 let cur_off = off + cur_x * 4 + cur_y * 4 * stride;
86 frm.data[cur_off + i + j * stride] = clr;
90 } else if op < 0x8800 {
91 advance = (op & 0x3FF) as usize;
92 validate!(advance > 0);
93 skip_count += advance;
96 br.read_buf(&mut clr)?;
97 let mut flags = !op as usize;
98 let cur_off = off + cur_x * 4 + cur_y * 4 * stride;
101 frm.data[cur_off + i + j * stride] = clr[(i >> 1) * 2 + (j >> 1) * 4 + (flags & 1)];
108 while cur_x >= blk_w {
113 validate!(cur_x == 0 && cur_y == blk_h);
116 } else if skip_count < blk_w * blk_h {
122 fn decode_frame16(&self, br: &mut ByteReader, frm: &mut NASimpleVideoFrame<u16>) -> DecoderResult<FrameType> {
123 let off = frm.offset[0];
124 let stride = frm.stride[0];
125 let mut skip_count = 0;
126 let blk_w = (self.width + 3) >> 2;
127 let blk_h = (self.height + 3) >> 2;
130 while cur_x < blk_w && cur_y < blk_h {
131 let op = br.read_u16le()?;
133 if (op & 0x8000) == 0 {
134 let mut clr = [0; 8];
135 clr[0] = br.read_u16le()?;
136 clr[1] = br.read_u16le()?;
137 let mut flags = !op as usize;
138 let cur_off = off + cur_x * 4 + cur_y * 4 * stride;
139 if (clr[0] & 0x8000) == 0 {
142 frm.data[cur_off + i + j * stride] = clr[flags & 1];
147 clr[2] = br.read_u16le()?;
148 clr[3] = br.read_u16le()?;
149 clr[4] = br.read_u16le()?;
150 clr[5] = br.read_u16le()?;
151 clr[6] = br.read_u16le()?;
152 clr[7] = br.read_u16le()?;
155 frm.data[cur_off + i + j * stride] = clr[(i >> 1) * 2 + (j >> 1) * 4 + (flags & 1)];
161 } else if (op & 0xFC00) == 0x8400 {
162 advance = (op & 0x3FF) as usize;
163 validate!(advance > 0);
164 skip_count += advance;
166 let cur_off = off + cur_x * 4 + cur_y * 4 * stride;
167 let clr = op & 0x7FFF;
170 frm.data[cur_off + i + j * stride] = clr;
176 while cur_x >= blk_w {
181 validate!((cur_x == 0 || cur_x == 1) && cur_y == blk_h);
184 } else if skip_count < blk_w * blk_h {
192 impl NADecoder for Video1Decoder {
193 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
194 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
195 self.is_16bit = !vinfo.get_format().palette;
196 let fmt = if !self.is_16bit { PAL8_FORMAT } else { RGB555_FORMAT };
197 self.width = vinfo.get_width();
198 self.height = vinfo.get_height();
199 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(self.width, self.height, true, fmt));
200 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
204 Err(DecoderError::InvalidData)
207 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
208 let src = pkt.get_buffer();
209 validate!(src.len() >= 2);
210 let mut mr = MemoryReader::new_read(src.as_slice());
211 let mut br = ByteReader::new(&mut mr);
216 let bufret = self.hams.clone_ref();
218 if let Some(bbuf) = bufret {
221 let bufinfo = alloc_video_buffer(self.info.get_properties().get_video_info().unwrap(), 2)?;
222 buf = bufinfo.get_vbuf().unwrap();
223 self.hams.add_frame(buf);
224 buf = self.hams.get_output_frame().unwrap();
226 let mut frm = NASimpleVideoFrame::from_video_buf(&mut buf).unwrap();
227 ftype = self.decode_frame(&mut br, &mut frm)?;
228 let paloff = frm.offset[1];
229 let dpal = &mut frm.data[paloff..];
230 let mut found_pal = false;
231 for sd in pkt.side_data.iter() {
233 NASideData::Palette(_, ref pal) => {
234 for (dst, src) in dpal.chunks_mut(3).zip(pal.chunks(4)) {
247 dpal[i * 3 + 0] = i as u8;
248 dpal[i * 3 + 1] = i as u8;
249 dpal[i * 3 + 2] = i as u8;
252 buftype = NABufferType::Video(buf);
254 let bufret = self.hams16.clone_ref();
256 if let Some(bbuf) = bufret {
259 let bufinfo = alloc_video_buffer(self.info.get_properties().get_video_info().unwrap(), 2)?;
260 buf = bufinfo.get_vbuf16().unwrap();
261 self.hams16.add_frame(buf);
262 buf = self.hams16.get_output_frame().unwrap();
264 let mut frm = NASimpleVideoFrame::from_video_buf(&mut buf).unwrap();
265 ftype = self.decode_frame16(&mut br, &mut frm)?;
266 buftype = NABufferType::Video16(buf);
269 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), buftype);
270 frm.set_keyframe(ftype == FrameType::I);
271 frm.set_frame_type(ftype);
274 fn flush(&mut self) {
280 impl NAOptionHandler for Video1Decoder {
281 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
282 fn set_options(&mut self, _options: &[NAOption]) { }
283 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
286 pub fn get_decoder() -> Box<dyn NADecoder + Send> {
287 Box::new(Video1Decoder::new())
292 use nihav_core::codecs::RegisteredDecoders;
293 use nihav_core::demuxers::RegisteredDemuxers;
294 use nihav_codec_support::test::dec_video::*;
295 use crate::ms_register_all_codecs;
296 use nihav_commonfmt::generic_register_all_demuxers;
298 fn test_ms_video1_8bit() {
299 let mut dmx_reg = RegisteredDemuxers::new();
300 generic_register_all_demuxers(&mut dmx_reg);
301 let mut dec_reg = RegisteredDecoders::new();
302 ms_register_all_codecs(&mut dec_reg);
304 test_decoding("avi", "msvideo1", "assets/MS/toon.avi", Some(66), &dmx_reg, &dec_reg,
305 ExpectedTestResult::MD5([0x0c26ec42, 0xb75bfea7, 0x1e6342ae, 0xb14dcfa3]));
308 fn test_ms_video1_16bit() {
309 let mut dmx_reg = RegisteredDemuxers::new();
310 generic_register_all_demuxers(&mut dmx_reg);
311 let mut dec_reg = RegisteredDecoders::new();
312 ms_register_all_codecs(&mut dec_reg);
314 test_decoding("avi", "msvideo1", "assets/MS/clock-cram16.avi", None, &dmx_reg, &dec_reg,
315 ExpectedTestResult::MD5([0x03381fa4, 0x5b294fec, 0xb97a7575, 0xa1a3ffe9]));