1 use nihav_core::frame::*;
2 use nihav_core::codecs::*;
3 use nihav_core::io::byteio::*;
4 use nihav_core::compr::deflate::*;
8 lastframe: Option<NAVideoBufferRef<u8>>,
9 keyframe: Option<NAVideoBufferRef<u8>>,
14 fn new() -> Self { Self::default() }
17 self.lastframe = None;
19 fn add_frame(&mut self, buf: NAVideoBufferRef<u8>) {
20 self.lastframe = Some(buf);
22 fn add_keyframe(&mut self, buf: NAVideoBufferRef<u8>) {
23 self.keyframe = Some(buf);
25 fn clone_ref(&mut self) -> Option<NAVideoBufferRef<u8>> {
26 if let Some(ref mut frm) = self.lastframe {
27 let newfrm = frm.copy_buffer();
28 *frm = newfrm.clone().into_ref();
29 Some(newfrm.into_ref())
34 fn has_last_frame(&self) -> bool { self.lastframe.is_some() }
35 fn get_key_frame(&mut self) -> Option<NAVideoBufferRef<u8>> {
37 Some(ref frm) => Some(frm.clone()),
41 fn get_last_frame(&mut self) -> Option<NAVideoBufferRef<u8>> {
42 match self.lastframe {
43 Some(ref frm) => Some(frm.clone()),
70 fn new(ver1: bool) -> Self {
72 info: NACodecInfo::new_dummy(),
73 shuf: FSVShuffler::new(),
84 inflate: Inflate::new(),
90 fn decode_v1(&mut self, br: &mut ByteReader, data: &mut [u8], stride: usize) -> DecoderResult<bool> {
91 let mut is_intra = true;
92 for (yy, row) in data.chunks_mut(stride * self.block_h).enumerate() {
93 let cur_h = (self.h - yy * self.block_h).min(self.block_h);
94 for x in (0..self.w).step_by(self.block_w) {
95 let cur_w = (self.w - x).min(self.block_w);
97 let data_size = br.read_u16be()? as usize;
99 br.read_buf(&mut self.cbuf[..data_size])?;
100 self.inflate = Inflate::new();
101 if self.inflate.decompress_block(&self.cbuf[..data_size], &mut self.tile[..cur_w * cur_h * 3]).is_err() {
102 return Err(DecoderError::InvalidData);
104 for (dst, src) in row[x * 3..].chunks_mut(stride).zip(self.tile.chunks(cur_w * 3)) {
105 dst[..cur_w * 3].copy_from_slice(src);
114 fn decode_v2(&mut self, br: &mut ByteReader, data: &mut [u8], stride: usize, keyframe: bool) -> DecoderResult<bool> {
115 let mut is_intra = !self.has_ifrm;
116 let bstride = (self.w + self.block_w - 1) / self.block_w;
117 for y in (0..self.h).step_by(self.block_h) {
118 let cur_h = (self.h - y).min(self.block_h);
119 for x in (0..self.w).step_by(self.block_w) {
120 let cur_w = (self.w - x).min(self.block_w);
122 let mut data_size = br.read_u16be()? as usize;
123 validate!(!keyframe || data_size > 0);
128 let blk_start = br.tell();
129 let flags = br.read_byte()?;
130 let depth = (flags >> 3) & 3;
131 validate!(depth == 0 || depth == 2);
132 let has_diff = (flags & 4) != 0;
133 let cpriming = (flags & 2) != 0;
134 let ppriming = (flags & 1) != 0;
135 let (start, height) = if has_diff {
136 let start = br.read_byte()? as usize;
137 let height = br.read_byte()? as usize;
138 validate!(start + height <= cur_h);
144 let ret = self.shuf.get_key_frame();
146 return Err(DecoderError::MissingReference);
148 let src = ret.unwrap();
149 let src = src.get_data();
150 for (dst, src) in data[x * 3 + y * stride..].chunks_mut(stride).take(cur_h).zip(src[x * 3 + y * stride..].chunks(stride)) {
151 dst[..cur_w * 3].copy_from_slice(&src[..cur_w * 3]);
157 let ppos = if cpriming {
158 let xpos = br.read_byte()? as usize;
159 let ypos = br.read_byte()? as usize;
160 xpos + ypos * bstride
162 x / self.block_w + y / self.block_h * bstride
164 data_size -= (br.tell() - blk_start) as usize;
166 self.bpos.push(br.tell() as usize);
167 self.bsize.push(data_size);
170 br.read_buf(&mut self.cbuf[..data_size])?;
171 self.inflate = Inflate::new();
172 if cpriming || ppriming {
173 if self.bpos.is_empty() {
174 return Err(DecoderError::MissingReference);
176 let ret = self.inflate.decompress_block(&self.kdata[self.bpos[ppos]..][..self.bsize[ppos]], &mut self.tile);
178 return Err(DecoderError::InvalidData);
180 let ssize = ret.unwrap();
181 self.inflate = Inflate::new();
182 self.inflate.set_dict(&self.tile[..ssize]);
184 let ret = self.inflate.decompress_block(&self.cbuf[..data_size], &mut self.tile[..cur_w * height * 3]);
186 return Err(DecoderError::InvalidData);
188 let src_len = ret.unwrap();
190 let dst = &mut data[x * 3 + y * stride..];
193 validate!(src_len == cur_w * cur_h * 3);
194 for (dst, src) in dst.chunks_mut(stride).skip(start).take(height).zip(self.tile.chunks(cur_w * 3)) {
195 dst[..cur_w * 3].copy_from_slice(src);
199 let mut mr = MemoryReader::new_read(&self.tile[..src_len]);
200 let mut br = ByteReader::new(&mut mr);
201 for line in dst.chunks_mut(stride).skip(start).take(height) {
202 for rgb in line.chunks_mut(3).take(cur_w) {
203 let b = br.read_byte()?;
205 rgb.copy_from_slice(&self.pal[(b as usize) * 3..][..3]);
207 let c = br.read_byte()?;
208 let clr = (u16::from(b & 0x7F) << 8) | u16::from(c);
209 let r = (clr >> 10) as u8;
210 let g = ((clr >> 5) & 0x1F) as u8;
211 let b = (clr & 0x1F) as u8;
212 rgb[0] = (r << 3) | (r >> 2);
213 rgb[1] = (g << 3) | (g >> 2);
214 rgb[2] = (b << 3) | (b >> 2);
233 impl NADecoder for FSVDecoder {
234 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
235 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
236 let w = vinfo.get_width();
237 let h = vinfo.get_height();
238 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(w, h, true, RGB24_FORMAT));
239 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
243 Err(DecoderError::InvalidData)
246 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
247 let src = pkt.get_buffer();
249 validate!(src.len() > 4);
250 let mut mr = MemoryReader::new_read(&src);
251 let mut br = ByteReader::new(&mut mr);
253 let hdr0 = br.read_u16be()? as usize;
254 let hdr1 = br.read_u16be()? as usize;
255 let w = hdr0 & 0xFFF;
256 let h = hdr1 & 0xFFF;
257 let blk_w = (hdr0 >> 12) * 16 + 16;
258 let blk_h = (hdr1 >> 12) * 16 + 16;
259 validate!(w != 0 && h != 0 && blk_w != 0 && blk_h != 0);
262 let flags = br.read_byte()?;
263 self.has_pal = (flags & 1) != 0;
264 self.has_ifrm = (flags & 2) != 0;
266 let pal_sz = br.read_u16be()? as usize;
267 br.read_buf(&mut self.cbuf[..pal_sz])?;
268 self.inflate = Inflate::new();
269 if self.inflate.decompress_block(&self.cbuf[..pal_sz], &mut self.pal).is_err() {
270 return Err(DecoderError::InvalidData);
275 self.kdata.extend_from_slice(&src);
280 if self.w != w || self.h != h || self.block_w != blk_w || self.block_h != blk_h {
282 self.tile.resize(blk_w * blk_h * 3, 0);
285 self.block_w = blk_w;
286 self.block_h = blk_h;
289 let mut buf = if let Some(buffer) = self.shuf.clone_ref() {
292 let vinfo = self.info.get_properties().get_video_info().unwrap();
293 let bufinfo = alloc_video_buffer(vinfo, 0)?;
294 bufinfo.get_vbuf().unwrap()
296 let stride = buf.get_stride(0);
297 let data = buf.get_data_mut().unwrap();
298 let is_intra = if self.ver1 {
299 self.decode_v1(&mut br, data, stride)?
301 self.decode_v2(&mut br, data, stride, pkt.keyframe)?
304 if !is_intra && !self.shuf.has_last_frame() {
305 return Err(DecoderError::MissingReference);
308 if pkt.is_keyframe() {
309 self.shuf.add_keyframe(buf.clone());
311 self.shuf.add_frame(buf.clone());
313 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), NABufferType::VideoPacked(buf));
314 frm.set_frame_type(if is_intra { FrameType::I } else { FrameType::P });
317 fn flush(&mut self) {
322 impl NAOptionHandler for FSVDecoder {
323 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
324 fn set_options(&mut self, _options: &[NAOption]) { }
325 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
328 pub fn get_decoder() -> Box<dyn NADecoder + Send> {
329 Box::new(FSVDecoder::new(true))
332 pub fn get_decoder_v2() -> Box<dyn NADecoder + Send> {
333 Box::new(FSVDecoder::new(false))
338 use nihav_core::codecs::RegisteredDecoders;
339 use nihav_core::demuxers::RegisteredDemuxers;
340 use nihav_codec_support::test::dec_video::*;
341 use crate::flash_register_all_decoders;
342 use crate::flash_register_all_demuxers;
345 let mut dmx_reg = RegisteredDemuxers::new();
346 flash_register_all_demuxers(&mut dmx_reg);
347 let mut dec_reg = RegisteredDecoders::new();
348 flash_register_all_decoders(&mut dec_reg);
350 test_decoding("flv", "flashsv", "assets/Flash/screen.flv",
351 Some(3000), &dmx_reg, &dec_reg, ExpectedTestResult::MD5Frames(vec![
352 [0xb45b899e, 0x417b17d5, 0x7bfe898b, 0x026b289f],
353 [0xb45b899e, 0x417b17d5, 0x7bfe898b, 0x026b289f],
354 [0xb45b899e, 0x417b17d5, 0x7bfe898b, 0x026b289f],
355 [0xb45b899e, 0x417b17d5, 0x7bfe898b, 0x026b289f],
356 [0xb45b899e, 0x417b17d5, 0x7bfe898b, 0x026b289f],
357 [0xb45b899e, 0x417b17d5, 0x7bfe898b, 0x026b289f],
358 [0xb45b899e, 0x417b17d5, 0x7bfe898b, 0x026b289f],
359 [0xb45b899e, 0x417b17d5, 0x7bfe898b, 0x026b289f],
360 [0xc04d4d1c, 0xbb1f4b4f, 0xe9f3d85e, 0xa40aff68],
361 [0x172e5bbe, 0xe44caba3, 0x6cb2a263, 0xcb79a89a]]));
365 let mut dmx_reg = RegisteredDemuxers::new();
366 flash_register_all_demuxers(&mut dmx_reg);
367 let mut dec_reg = RegisteredDecoders::new();
368 flash_register_all_decoders(&mut dec_reg);
370 test_decoding("flv", "flashsv2", "assets/Flash/screen2.flv",
371 Some(4700), &dmx_reg, &dec_reg, ExpectedTestResult::MD5Frames(vec![
372 [0x55522afa, 0x9c7dd794, 0xdd67aa2e, 0x8b8c525e],
373 [0x55522afa, 0x9c7dd794, 0xdd67aa2e, 0x8b8c525e],
374 [0x55522afa, 0x9c7dd794, 0xdd67aa2e, 0x8b8c525e],
375 [0x55522afa, 0x9c7dd794, 0xdd67aa2e, 0x8b8c525e],
376 [0x55522afa, 0x9c7dd794, 0xdd67aa2e, 0x8b8c525e],
377 [0x55522afa, 0x9c7dd794, 0xdd67aa2e, 0x8b8c525e],
378 [0x55522afa, 0x9c7dd794, 0xdd67aa2e, 0x8b8c525e],
379 [0x55522afa, 0x9c7dd794, 0xdd67aa2e, 0x8b8c525e],
380 [0x9809efc2, 0xec5385aa, 0xb5eb9320, 0x4a47188e],
381 [0x40c77877, 0x58183722, 0x5700eb17, 0x27a00e33],
382 [0x802c2c6a, 0x3e08dd62, 0xa6c94df3, 0xc6318a6f],
383 [0x2aa70255, 0x652f0ca4, 0xe79817f9, 0x4f67e7ba],
384 [0x5cf34d91, 0xdfc54992, 0x4368180d, 0xfbe747d4],
385 [0x266d8bc4, 0x2b492ef4, 0xb42401a0, 0x23e530ec],
386 [0xa0e46b1c, 0x47d0620e, 0x0cbcb15b, 0x243e7f13]]));
390 const DEFAULT_PAL: [u8; 128 * 3] = [
391 0x00, 0x00, 0x00, 0x33, 0x33, 0x33, 0x66, 0x66, 0x66, 0x99, 0x99, 0x99,
392 0xCC, 0xCC, 0xCC, 0xFF, 0xFF, 0xFF, 0x33, 0x00, 0x00, 0x66, 0x00, 0x00,
393 0x99, 0x00, 0x00, 0xCC, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x33, 0x00,
394 0x00, 0x66, 0x00, 0x00, 0x99, 0x00, 0x00, 0xCC, 0x00, 0x00, 0xFF, 0x00,
395 0x00, 0x00, 0x33, 0x00, 0x00, 0x66, 0x00, 0x00, 0x99, 0x00, 0x00, 0xCC,
396 0x00, 0x00, 0xFF, 0x33, 0x33, 0x00, 0x66, 0x66, 0x00, 0x99, 0x99, 0x00,
397 0xCC, 0xCC, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x33, 0x33, 0x00, 0x66, 0x66,
398 0x00, 0x99, 0x99, 0x00, 0xCC, 0xCC, 0x00, 0xFF, 0xFF, 0x33, 0x00, 0x33,
399 0x66, 0x00, 0x66, 0x99, 0x00, 0x99, 0xCC, 0x00, 0xCC, 0xFF, 0x00, 0xFF,
400 0xFF, 0xFF, 0x33, 0xFF, 0xFF, 0x66, 0xFF, 0xFF, 0x99, 0xFF, 0xFF, 0xCC,
401 0xFF, 0x33, 0xFF, 0xFF, 0x66, 0xFF, 0xFF, 0x99, 0xFF, 0xFF, 0xCC, 0xFF,
402 0x33, 0xFF, 0xFF, 0x66, 0xFF, 0xFF, 0x99, 0xFF, 0xFF, 0xCC, 0xFF, 0xFF,
403 0xCC, 0xCC, 0x33, 0xCC, 0xCC, 0x66, 0xCC, 0xCC, 0x99, 0xCC, 0xCC, 0xFF,
404 0xCC, 0x33, 0xCC, 0xCC, 0x66, 0xCC, 0xCC, 0x99, 0xCC, 0xCC, 0xFF, 0xCC,
405 0x33, 0xCC, 0xCC, 0x66, 0xCC, 0xCC, 0x99, 0xCC, 0xCC, 0xFF, 0xCC, 0xCC,
406 0x99, 0x99, 0x33, 0x99, 0x99, 0x66, 0x99, 0x99, 0xCC, 0x99, 0x99, 0xFF,
407 0x99, 0x33, 0x99, 0x99, 0x66, 0x99, 0x99, 0xCC, 0x99, 0x99, 0xFF, 0x99,
408 0x33, 0x99, 0x99, 0x66, 0x99, 0x99, 0xCC, 0x99, 0x99, 0xFF, 0x99, 0x99,
409 0x66, 0x66, 0x33, 0x66, 0x66, 0x99, 0x66, 0x66, 0xCC, 0x66, 0x66, 0xFF,
410 0x66, 0x33, 0x66, 0x66, 0x99, 0x66, 0x66, 0xCC, 0x66, 0x66, 0xFF, 0x66,
411 0x33, 0x66, 0x66, 0x99, 0x66, 0x66, 0xCC, 0x66, 0x66, 0xFF, 0x66, 0x66,
412 0x33, 0x33, 0x66, 0x33, 0x33, 0x99, 0x33, 0x33, 0xCC, 0x33, 0x33, 0xFF,
413 0x33, 0x66, 0x33, 0x33, 0x99, 0x33, 0x33, 0xCC, 0x33, 0x33, 0xFF, 0x33,
414 0x66, 0x33, 0x33, 0x99, 0x33, 0x33, 0xCC, 0x33, 0x33, 0xFF, 0x33, 0x33,
415 0x00, 0x33, 0x66, 0x33, 0x66, 0x00, 0x66, 0x00, 0x33, 0x00, 0x66, 0x33,
416 0x33, 0x00, 0x66, 0x66, 0x33, 0x00, 0x33, 0x66, 0x99, 0x66, 0x99, 0x33,
417 0x99, 0x33, 0x66, 0x33, 0x99, 0x66, 0x66, 0x33, 0x99, 0x99, 0x66, 0x33,
418 0x66, 0x99, 0xCC, 0x99, 0xCC, 0x66, 0xCC, 0x66, 0x99, 0x66, 0xCC, 0x99,
419 0x99, 0x66, 0xCC, 0xCC, 0x99, 0x66, 0x99, 0xCC, 0xFF, 0xCC, 0xFF, 0x99,
420 0xFF, 0x99, 0xCC, 0x99, 0xFF, 0xCC, 0xCC, 0x99, 0xFF, 0xFF, 0xCC, 0x99,
421 0x11, 0x11, 0x11, 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x55, 0x55, 0x55,
422 0xAA, 0xAA, 0xAA, 0xBB, 0xBB, 0xBB, 0xDD, 0xDD, 0xDD, 0xEE, 0xEE, 0xEE