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>> {
36 self.keyframe.as_ref().cloned()
38 fn get_last_frame(&mut self) -> Option<NAVideoBufferRef<u8>> {
39 self.lastframe.as_ref().cloned()
64 fn new(ver1: bool) -> Self {
66 info: NACodecInfo::new_dummy(),
67 shuf: FSVShuffler::new(),
78 inflate: Inflate::new(),
84 fn decode_v1(&mut self, br: &mut ByteReader, data: &mut [u8], stride: usize) -> DecoderResult<bool> {
85 let mut is_intra = true;
86 for (yy, row) in data.chunks_mut(stride * self.block_h).enumerate() {
87 let cur_h = (self.h - yy * self.block_h).min(self.block_h);
88 for x in (0..self.w).step_by(self.block_w) {
89 let cur_w = (self.w - x).min(self.block_w);
91 let data_size = br.read_u16be()? as usize;
93 br.read_buf(&mut self.cbuf[..data_size])?;
94 self.inflate = Inflate::new();
95 if self.inflate.decompress_block(&self.cbuf[..data_size], &mut self.tile[..cur_w * cur_h * 3]).is_err() {
96 return Err(DecoderError::InvalidData);
98 for (dst, src) in row[x * 3..].chunks_mut(stride).zip(self.tile.chunks(cur_w * 3)) {
99 dst[..cur_w * 3].copy_from_slice(src);
108 fn decode_v2(&mut self, br: &mut ByteReader, data: &mut [u8], stride: usize, keyframe: bool) -> DecoderResult<bool> {
109 let mut is_intra = !self.has_ifrm;
110 let bstride = (self.w + self.block_w - 1) / self.block_w;
111 for y in (0..self.h).step_by(self.block_h) {
112 let cur_h = (self.h - y).min(self.block_h);
113 for x in (0..self.w).step_by(self.block_w) {
114 let cur_w = (self.w - x).min(self.block_w);
116 let mut data_size = br.read_u16be()? as usize;
117 validate!(!keyframe || data_size > 0);
122 let blk_start = br.tell();
123 let flags = br.read_byte()?;
124 let depth = (flags >> 3) & 3;
125 validate!(depth == 0 || depth == 2);
126 let has_diff = (flags & 4) != 0;
127 let cpriming = (flags & 2) != 0;
128 let ppriming = (flags & 1) != 0;
129 let (start, height) = if has_diff {
130 let start = br.read_byte()? as usize;
131 let height = br.read_byte()? as usize;
132 validate!(start + height <= cur_h);
138 let ret = self.shuf.get_key_frame();
140 return Err(DecoderError::MissingReference);
142 let src = ret.unwrap();
143 let src = src.get_data();
144 for (dst, src) in data[x * 3 + y * stride..].chunks_mut(stride).take(cur_h).zip(src[x * 3 + y * stride..].chunks(stride)) {
145 dst[..cur_w * 3].copy_from_slice(&src[..cur_w * 3]);
151 let ppos = if cpriming {
152 let xpos = br.read_byte()? as usize;
153 let ypos = br.read_byte()? as usize;
154 xpos + ypos * bstride
156 x / self.block_w + y / self.block_h * bstride
158 data_size -= (br.tell() - blk_start) as usize;
160 self.bpos.push(br.tell() as usize);
161 self.bsize.push(data_size);
164 br.read_buf(&mut self.cbuf[..data_size])?;
165 self.inflate = Inflate::new();
166 if cpriming || ppriming {
167 if self.bpos.is_empty() {
168 return Err(DecoderError::MissingReference);
170 let ret = self.inflate.decompress_block(&self.kdata[self.bpos[ppos]..][..self.bsize[ppos]], &mut self.tile);
172 return Err(DecoderError::InvalidData);
174 let ssize = ret.unwrap();
175 self.inflate = Inflate::new();
176 self.inflate.set_dict(&self.tile[..ssize]);
178 let ret = self.inflate.decompress_block(&self.cbuf[..data_size], &mut self.tile[..cur_w * height * 3]);
180 return Err(DecoderError::InvalidData);
182 let src_len = ret.unwrap();
184 let dst = &mut data[x * 3 + y * stride..];
187 validate!(src_len == cur_w * cur_h * 3);
188 for (dst, src) in dst.chunks_mut(stride).skip(start).take(height).zip(self.tile.chunks(cur_w * 3)) {
189 dst[..cur_w * 3].copy_from_slice(src);
193 let mut mr = MemoryReader::new_read(&self.tile[..src_len]);
194 let mut br = ByteReader::new(&mut mr);
195 for line in dst.chunks_mut(stride).skip(start).take(height) {
196 for rgb in line.chunks_mut(3).take(cur_w) {
197 let b = br.read_byte()?;
199 rgb.copy_from_slice(&self.pal[(b as usize) * 3..][..3]);
201 let c = br.read_byte()?;
202 let clr = (u16::from(b & 0x7F) << 8) | u16::from(c);
203 let r = (clr >> 10) as u8;
204 let g = ((clr >> 5) & 0x1F) as u8;
205 let b = (clr & 0x1F) as u8;
206 rgb[0] = (r << 3) | (r >> 2);
207 rgb[1] = (g << 3) | (g >> 2);
208 rgb[2] = (b << 3) | (b >> 2);
227 impl NADecoder for FSVDecoder {
228 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
229 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
230 let w = vinfo.get_width();
231 let h = vinfo.get_height();
232 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(w, h, true, RGB24_FORMAT));
233 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
237 Err(DecoderError::InvalidData)
240 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
241 let src = pkt.get_buffer();
243 validate!(src.len() > 4);
244 let mut mr = MemoryReader::new_read(&src);
245 let mut br = ByteReader::new(&mut mr);
247 let hdr0 = br.read_u16be()? as usize;
248 let hdr1 = br.read_u16be()? as usize;
249 let w = hdr0 & 0xFFF;
250 let h = hdr1 & 0xFFF;
251 let blk_w = (hdr0 >> 12) * 16 + 16;
252 let blk_h = (hdr1 >> 12) * 16 + 16;
253 validate!(w != 0 && h != 0 && blk_w != 0 && blk_h != 0);
256 let flags = br.read_byte()?;
257 self.has_pal = (flags & 1) != 0;
258 self.has_ifrm = (flags & 2) != 0;
260 let pal_sz = br.read_u16be()? as usize;
261 br.read_buf(&mut self.cbuf[..pal_sz])?;
262 self.inflate = Inflate::new();
263 if self.inflate.decompress_block(&self.cbuf[..pal_sz], &mut self.pal).is_err() {
264 return Err(DecoderError::InvalidData);
269 self.kdata.extend_from_slice(&src);
274 if self.w != w || self.h != h || self.block_w != blk_w || self.block_h != blk_h {
276 self.tile.resize(blk_w * blk_h * 3, 0);
279 self.block_w = blk_w;
280 self.block_h = blk_h;
283 let mut buf = if let Some(buffer) = self.shuf.clone_ref() {
286 let vinfo = self.info.get_properties().get_video_info().unwrap();
287 let bufinfo = alloc_video_buffer(vinfo, 0)?;
288 bufinfo.get_vbuf().unwrap()
290 let stride = buf.get_stride(0);
291 let data = buf.get_data_mut().unwrap();
292 let is_intra = if self.ver1 {
293 self.decode_v1(&mut br, data, stride)?
295 self.decode_v2(&mut br, data, stride, pkt.keyframe)?
298 if !is_intra && !self.shuf.has_last_frame() {
299 return Err(DecoderError::MissingReference);
302 if pkt.is_keyframe() {
303 self.shuf.add_keyframe(buf.clone());
305 self.shuf.add_frame(buf.clone());
307 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), NABufferType::VideoPacked(buf));
308 frm.set_frame_type(if is_intra { FrameType::I } else { FrameType::P });
311 fn flush(&mut self) {
316 impl NAOptionHandler for FSVDecoder {
317 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
318 fn set_options(&mut self, _options: &[NAOption]) { }
319 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
322 pub fn get_decoder() -> Box<dyn NADecoder + Send> {
323 Box::new(FSVDecoder::new(true))
326 pub fn get_decoder_v2() -> Box<dyn NADecoder + Send> {
327 Box::new(FSVDecoder::new(false))
332 use nihav_core::codecs::RegisteredDecoders;
333 use nihav_core::demuxers::RegisteredDemuxers;
334 use nihav_codec_support::test::dec_video::*;
335 use crate::flash_register_all_decoders;
336 use crate::flash_register_all_demuxers;
339 let mut dmx_reg = RegisteredDemuxers::new();
340 flash_register_all_demuxers(&mut dmx_reg);
341 let mut dec_reg = RegisteredDecoders::new();
342 flash_register_all_decoders(&mut dec_reg);
344 // sample: https://samples.mplayerhq.hu/FLV/flash_screen/screen.flv
345 test_decoding("flv", "flashsv", "assets/Flash/screen.flv",
346 Some(3000), &dmx_reg, &dec_reg, ExpectedTestResult::MD5Frames(vec![
347 [0xb45b899e, 0x417b17d5, 0x7bfe898b, 0x026b289f],
348 [0xb45b899e, 0x417b17d5, 0x7bfe898b, 0x026b289f],
349 [0xb45b899e, 0x417b17d5, 0x7bfe898b, 0x026b289f],
350 [0xb45b899e, 0x417b17d5, 0x7bfe898b, 0x026b289f],
351 [0xb45b899e, 0x417b17d5, 0x7bfe898b, 0x026b289f],
352 [0xb45b899e, 0x417b17d5, 0x7bfe898b, 0x026b289f],
353 [0xb45b899e, 0x417b17d5, 0x7bfe898b, 0x026b289f],
354 [0xb45b899e, 0x417b17d5, 0x7bfe898b, 0x026b289f],
355 [0xc04d4d1c, 0xbb1f4b4f, 0xe9f3d85e, 0xa40aff68],
356 [0x172e5bbe, 0xe44caba3, 0x6cb2a263, 0xcb79a89a]]));
360 let mut dmx_reg = RegisteredDemuxers::new();
361 flash_register_all_demuxers(&mut dmx_reg);
362 let mut dec_reg = RegisteredDecoders::new();
363 flash_register_all_decoders(&mut dec_reg);
365 // sample created from https://samples.mplayerhq.hu/FLV/flash_screen/screen.flv by recoding
366 test_decoding("flv", "flashsv2", "assets/Flash/screen2.flv",
367 Some(4700), &dmx_reg, &dec_reg, ExpectedTestResult::MD5Frames(vec![
368 [0x55522afa, 0x9c7dd794, 0xdd67aa2e, 0x8b8c525e],
369 [0x55522afa, 0x9c7dd794, 0xdd67aa2e, 0x8b8c525e],
370 [0x55522afa, 0x9c7dd794, 0xdd67aa2e, 0x8b8c525e],
371 [0x55522afa, 0x9c7dd794, 0xdd67aa2e, 0x8b8c525e],
372 [0x55522afa, 0x9c7dd794, 0xdd67aa2e, 0x8b8c525e],
373 [0x55522afa, 0x9c7dd794, 0xdd67aa2e, 0x8b8c525e],
374 [0x55522afa, 0x9c7dd794, 0xdd67aa2e, 0x8b8c525e],
375 [0x55522afa, 0x9c7dd794, 0xdd67aa2e, 0x8b8c525e],
376 [0x9809efc2, 0xec5385aa, 0xb5eb9320, 0x4a47188e],
377 [0x40c77877, 0x58183722, 0x5700eb17, 0x27a00e33],
378 [0x802c2c6a, 0x3e08dd62, 0xa6c94df3, 0xc6318a6f],
379 [0x2aa70255, 0x652f0ca4, 0xe79817f9, 0x4f67e7ba],
380 [0x5cf34d91, 0xdfc54992, 0x4368180d, 0xfbe747d4],
381 [0x266d8bc4, 0x2b492ef4, 0xb42401a0, 0x23e530ec],
382 [0xa0e46b1c, 0x47d0620e, 0x0cbcb15b, 0x243e7f13]]));
386 const DEFAULT_PAL: [u8; 128 * 3] = [
387 0x00, 0x00, 0x00, 0x33, 0x33, 0x33, 0x66, 0x66, 0x66, 0x99, 0x99, 0x99,
388 0xCC, 0xCC, 0xCC, 0xFF, 0xFF, 0xFF, 0x33, 0x00, 0x00, 0x66, 0x00, 0x00,
389 0x99, 0x00, 0x00, 0xCC, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x33, 0x00,
390 0x00, 0x66, 0x00, 0x00, 0x99, 0x00, 0x00, 0xCC, 0x00, 0x00, 0xFF, 0x00,
391 0x00, 0x00, 0x33, 0x00, 0x00, 0x66, 0x00, 0x00, 0x99, 0x00, 0x00, 0xCC,
392 0x00, 0x00, 0xFF, 0x33, 0x33, 0x00, 0x66, 0x66, 0x00, 0x99, 0x99, 0x00,
393 0xCC, 0xCC, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x33, 0x33, 0x00, 0x66, 0x66,
394 0x00, 0x99, 0x99, 0x00, 0xCC, 0xCC, 0x00, 0xFF, 0xFF, 0x33, 0x00, 0x33,
395 0x66, 0x00, 0x66, 0x99, 0x00, 0x99, 0xCC, 0x00, 0xCC, 0xFF, 0x00, 0xFF,
396 0xFF, 0xFF, 0x33, 0xFF, 0xFF, 0x66, 0xFF, 0xFF, 0x99, 0xFF, 0xFF, 0xCC,
397 0xFF, 0x33, 0xFF, 0xFF, 0x66, 0xFF, 0xFF, 0x99, 0xFF, 0xFF, 0xCC, 0xFF,
398 0x33, 0xFF, 0xFF, 0x66, 0xFF, 0xFF, 0x99, 0xFF, 0xFF, 0xCC, 0xFF, 0xFF,
399 0xCC, 0xCC, 0x33, 0xCC, 0xCC, 0x66, 0xCC, 0xCC, 0x99, 0xCC, 0xCC, 0xFF,
400 0xCC, 0x33, 0xCC, 0xCC, 0x66, 0xCC, 0xCC, 0x99, 0xCC, 0xCC, 0xFF, 0xCC,
401 0x33, 0xCC, 0xCC, 0x66, 0xCC, 0xCC, 0x99, 0xCC, 0xCC, 0xFF, 0xCC, 0xCC,
402 0x99, 0x99, 0x33, 0x99, 0x99, 0x66, 0x99, 0x99, 0xCC, 0x99, 0x99, 0xFF,
403 0x99, 0x33, 0x99, 0x99, 0x66, 0x99, 0x99, 0xCC, 0x99, 0x99, 0xFF, 0x99,
404 0x33, 0x99, 0x99, 0x66, 0x99, 0x99, 0xCC, 0x99, 0x99, 0xFF, 0x99, 0x99,
405 0x66, 0x66, 0x33, 0x66, 0x66, 0x99, 0x66, 0x66, 0xCC, 0x66, 0x66, 0xFF,
406 0x66, 0x33, 0x66, 0x66, 0x99, 0x66, 0x66, 0xCC, 0x66, 0x66, 0xFF, 0x66,
407 0x33, 0x66, 0x66, 0x99, 0x66, 0x66, 0xCC, 0x66, 0x66, 0xFF, 0x66, 0x66,
408 0x33, 0x33, 0x66, 0x33, 0x33, 0x99, 0x33, 0x33, 0xCC, 0x33, 0x33, 0xFF,
409 0x33, 0x66, 0x33, 0x33, 0x99, 0x33, 0x33, 0xCC, 0x33, 0x33, 0xFF, 0x33,
410 0x66, 0x33, 0x33, 0x99, 0x33, 0x33, 0xCC, 0x33, 0x33, 0xFF, 0x33, 0x33,
411 0x00, 0x33, 0x66, 0x33, 0x66, 0x00, 0x66, 0x00, 0x33, 0x00, 0x66, 0x33,
412 0x33, 0x00, 0x66, 0x66, 0x33, 0x00, 0x33, 0x66, 0x99, 0x66, 0x99, 0x33,
413 0x99, 0x33, 0x66, 0x33, 0x99, 0x66, 0x66, 0x33, 0x99, 0x99, 0x66, 0x33,
414 0x66, 0x99, 0xCC, 0x99, 0xCC, 0x66, 0xCC, 0x66, 0x99, 0x66, 0xCC, 0x99,
415 0x99, 0x66, 0xCC, 0xCC, 0x99, 0x66, 0x99, 0xCC, 0xFF, 0xCC, 0xFF, 0x99,
416 0xFF, 0x99, 0xCC, 0x99, 0xFF, 0xCC, 0xCC, 0x99, 0xFF, 0xFF, 0xCC, 0x99,
417 0x11, 0x11, 0x11, 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x55, 0x55, 0x55,
418 0xAA, 0xAA, 0xAA, 0xBB, 0xBB, 0xBB, 0xDD, 0xDD, 0xDD, 0xEE, 0xEE, 0xEE