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 // sample: https://samples.mplayerhq.hu/FLV/flash_screen/screen.flv
351 test_decoding("flv", "flashsv", "assets/Flash/screen.flv",
352 Some(3000), &dmx_reg, &dec_reg, ExpectedTestResult::MD5Frames(vec![
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 [0xb45b899e, 0x417b17d5, 0x7bfe898b, 0x026b289f],
361 [0xc04d4d1c, 0xbb1f4b4f, 0xe9f3d85e, 0xa40aff68],
362 [0x172e5bbe, 0xe44caba3, 0x6cb2a263, 0xcb79a89a]]));
366 let mut dmx_reg = RegisteredDemuxers::new();
367 flash_register_all_demuxers(&mut dmx_reg);
368 let mut dec_reg = RegisteredDecoders::new();
369 flash_register_all_decoders(&mut dec_reg);
371 // sample created from https://samples.mplayerhq.hu/FLV/flash_screen/screen.flv by recoding
372 test_decoding("flv", "flashsv2", "assets/Flash/screen2.flv",
373 Some(4700), &dmx_reg, &dec_reg, ExpectedTestResult::MD5Frames(vec![
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 [0x55522afa, 0x9c7dd794, 0xdd67aa2e, 0x8b8c525e],
381 [0x55522afa, 0x9c7dd794, 0xdd67aa2e, 0x8b8c525e],
382 [0x9809efc2, 0xec5385aa, 0xb5eb9320, 0x4a47188e],
383 [0x40c77877, 0x58183722, 0x5700eb17, 0x27a00e33],
384 [0x802c2c6a, 0x3e08dd62, 0xa6c94df3, 0xc6318a6f],
385 [0x2aa70255, 0x652f0ca4, 0xe79817f9, 0x4f67e7ba],
386 [0x5cf34d91, 0xdfc54992, 0x4368180d, 0xfbe747d4],
387 [0x266d8bc4, 0x2b492ef4, 0xb42401a0, 0x23e530ec],
388 [0xa0e46b1c, 0x47d0620e, 0x0cbcb15b, 0x243e7f13]]));
392 const DEFAULT_PAL: [u8; 128 * 3] = [
393 0x00, 0x00, 0x00, 0x33, 0x33, 0x33, 0x66, 0x66, 0x66, 0x99, 0x99, 0x99,
394 0xCC, 0xCC, 0xCC, 0xFF, 0xFF, 0xFF, 0x33, 0x00, 0x00, 0x66, 0x00, 0x00,
395 0x99, 0x00, 0x00, 0xCC, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x33, 0x00,
396 0x00, 0x66, 0x00, 0x00, 0x99, 0x00, 0x00, 0xCC, 0x00, 0x00, 0xFF, 0x00,
397 0x00, 0x00, 0x33, 0x00, 0x00, 0x66, 0x00, 0x00, 0x99, 0x00, 0x00, 0xCC,
398 0x00, 0x00, 0xFF, 0x33, 0x33, 0x00, 0x66, 0x66, 0x00, 0x99, 0x99, 0x00,
399 0xCC, 0xCC, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x33, 0x33, 0x00, 0x66, 0x66,
400 0x00, 0x99, 0x99, 0x00, 0xCC, 0xCC, 0x00, 0xFF, 0xFF, 0x33, 0x00, 0x33,
401 0x66, 0x00, 0x66, 0x99, 0x00, 0x99, 0xCC, 0x00, 0xCC, 0xFF, 0x00, 0xFF,
402 0xFF, 0xFF, 0x33, 0xFF, 0xFF, 0x66, 0xFF, 0xFF, 0x99, 0xFF, 0xFF, 0xCC,
403 0xFF, 0x33, 0xFF, 0xFF, 0x66, 0xFF, 0xFF, 0x99, 0xFF, 0xFF, 0xCC, 0xFF,
404 0x33, 0xFF, 0xFF, 0x66, 0xFF, 0xFF, 0x99, 0xFF, 0xFF, 0xCC, 0xFF, 0xFF,
405 0xCC, 0xCC, 0x33, 0xCC, 0xCC, 0x66, 0xCC, 0xCC, 0x99, 0xCC, 0xCC, 0xFF,
406 0xCC, 0x33, 0xCC, 0xCC, 0x66, 0xCC, 0xCC, 0x99, 0xCC, 0xCC, 0xFF, 0xCC,
407 0x33, 0xCC, 0xCC, 0x66, 0xCC, 0xCC, 0x99, 0xCC, 0xCC, 0xFF, 0xCC, 0xCC,
408 0x99, 0x99, 0x33, 0x99, 0x99, 0x66, 0x99, 0x99, 0xCC, 0x99, 0x99, 0xFF,
409 0x99, 0x33, 0x99, 0x99, 0x66, 0x99, 0x99, 0xCC, 0x99, 0x99, 0xFF, 0x99,
410 0x33, 0x99, 0x99, 0x66, 0x99, 0x99, 0xCC, 0x99, 0x99, 0xFF, 0x99, 0x99,
411 0x66, 0x66, 0x33, 0x66, 0x66, 0x99, 0x66, 0x66, 0xCC, 0x66, 0x66, 0xFF,
412 0x66, 0x33, 0x66, 0x66, 0x99, 0x66, 0x66, 0xCC, 0x66, 0x66, 0xFF, 0x66,
413 0x33, 0x66, 0x66, 0x99, 0x66, 0x66, 0xCC, 0x66, 0x66, 0xFF, 0x66, 0x66,
414 0x33, 0x33, 0x66, 0x33, 0x33, 0x99, 0x33, 0x33, 0xCC, 0x33, 0x33, 0xFF,
415 0x33, 0x66, 0x33, 0x33, 0x99, 0x33, 0x33, 0xCC, 0x33, 0x33, 0xFF, 0x33,
416 0x66, 0x33, 0x33, 0x99, 0x33, 0x33, 0xCC, 0x33, 0x33, 0xFF, 0x33, 0x33,
417 0x00, 0x33, 0x66, 0x33, 0x66, 0x00, 0x66, 0x00, 0x33, 0x00, 0x66, 0x33,
418 0x33, 0x00, 0x66, 0x66, 0x33, 0x00, 0x33, 0x66, 0x99, 0x66, 0x99, 0x33,
419 0x99, 0x33, 0x66, 0x33, 0x99, 0x66, 0x66, 0x33, 0x99, 0x99, 0x66, 0x33,
420 0x66, 0x99, 0xCC, 0x99, 0xCC, 0x66, 0xCC, 0x66, 0x99, 0x66, 0xCC, 0x99,
421 0x99, 0x66, 0xCC, 0xCC, 0x99, 0x66, 0x99, 0xCC, 0xFF, 0xCC, 0xFF, 0x99,
422 0xFF, 0x99, 0xCC, 0x99, 0xFF, 0xCC, 0xCC, 0x99, 0xFF, 0xFF, 0xCC, 0x99,
423 0x11, 0x11, 0x11, 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x55, 0x55, 0x55,
424 0xAA, 0xAA, 0xAA, 0xBB, 0xBB, 0xBB, 0xDD, 0xDD, 0xDD, 0xEE, 0xEE, 0xEE