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>>,
13 fn new() -> Self { Self::default() }
16 self.lastframe = None;
18 fn add_frame(&mut self, buf: NAVideoBufferRef<u8>) {
19 self.lastframe = Some(buf);
21 fn add_keyframe(&mut self, buf: NAVideoBufferRef<u8>) {
22 self.keyframe = Some(buf);
24 fn clone_ref(&mut self) -> Option<NAVideoBufferRef<u8>> {
25 if let Some(ref mut frm) = self.lastframe {
26 let newfrm = frm.copy_buffer();
27 *frm = newfrm.clone().into_ref();
28 Some(newfrm.into_ref())
33 fn has_last_frame(&self) -> bool { self.lastframe.is_some() }
34 fn get_key_frame(&mut self) -> Option<NAVideoBufferRef<u8>> {
35 self.keyframe.as_ref().cloned()
37 /*fn get_last_frame(&mut self) -> Option<NAVideoBufferRef<u8>> {
38 self.lastframe.as_ref().cloned()
63 fn new(ver1: bool) -> Self {
65 info: NACodecInfo::new_dummy(),
66 shuf: FSVShuffler::new(),
77 inflate: Inflate::new(),
83 fn decode_v1(&mut self, br: &mut ByteReader, data: &mut [u8], stride: usize) -> DecoderResult<bool> {
84 let mut is_intra = true;
85 for (yy, row) in data.chunks_mut(stride * self.block_h).enumerate() {
86 let cur_h = (self.h - yy * self.block_h).min(self.block_h);
87 for x in (0..self.w).step_by(self.block_w) {
88 let cur_w = (self.w - x).min(self.block_w);
90 let data_size = br.read_u16be()? as usize;
92 br.read_buf(&mut self.cbuf[..data_size])?;
93 self.inflate = Inflate::new();
94 if self.inflate.decompress_block(&self.cbuf[..data_size], &mut self.tile[..cur_w * cur_h * 3]).is_err() {
95 return Err(DecoderError::InvalidData);
97 for (dst, src) in row[x * 3..].chunks_mut(stride).zip(self.tile.chunks(cur_w * 3)) {
98 dst[..cur_w * 3].copy_from_slice(src);
107 fn decode_v2(&mut self, br: &mut ByteReader, data: &mut [u8], stride: usize, keyframe: bool) -> DecoderResult<bool> {
108 let mut is_intra = !self.has_ifrm;
109 let bstride = (self.w + self.block_w - 1) / self.block_w;
110 for y in (0..self.h).step_by(self.block_h) {
111 let cur_h = (self.h - y).min(self.block_h);
112 for x in (0..self.w).step_by(self.block_w) {
113 let cur_w = (self.w - x).min(self.block_w);
115 let mut data_size = br.read_u16be()? as usize;
116 validate!(!keyframe || data_size > 0);
121 let blk_start = br.tell();
122 let flags = br.read_byte()?;
123 let depth = (flags >> 3) & 3;
124 validate!(depth == 0 || depth == 2);
125 let has_diff = (flags & 4) != 0;
126 let cpriming = (flags & 2) != 0;
127 let ppriming = (flags & 1) != 0;
128 let (start, height) = if has_diff {
129 let start = br.read_byte()? as usize;
130 let height = br.read_byte()? as usize;
131 validate!(start + height <= cur_h);
137 let ret = self.shuf.get_key_frame();
139 return Err(DecoderError::MissingReference);
141 let src = ret.unwrap();
142 let src = src.get_data();
143 for (dst, src) in data[x * 3 + y * stride..].chunks_mut(stride).take(cur_h).zip(src[x * 3 + y * stride..].chunks(stride)) {
144 dst[..cur_w * 3].copy_from_slice(&src[..cur_w * 3]);
150 let ppos = if cpriming {
151 let xpos = br.read_byte()? as usize;
152 let ypos = br.read_byte()? as usize;
153 xpos + ypos * bstride
155 x / self.block_w + y / self.block_h * bstride
157 data_size -= (br.tell() - blk_start) as usize;
159 self.bpos.push(br.tell() as usize);
160 self.bsize.push(data_size);
163 br.read_buf(&mut self.cbuf[..data_size])?;
164 self.inflate = Inflate::new();
165 if cpriming || ppriming {
166 if self.bpos.is_empty() {
167 return Err(DecoderError::MissingReference);
169 let ret = self.inflate.decompress_block(&self.kdata[self.bpos[ppos]..][..self.bsize[ppos]], &mut self.tile);
171 return Err(DecoderError::InvalidData);
173 let ssize = ret.unwrap();
174 self.inflate = Inflate::new();
175 self.inflate.set_dict(&self.tile[..ssize]);
177 let ret = self.inflate.decompress_block(&self.cbuf[..data_size], &mut self.tile[..cur_w * height * 3]);
179 return Err(DecoderError::InvalidData);
181 let src_len = ret.unwrap();
183 let dst = &mut data[x * 3 + y * stride..];
186 validate!(src_len == cur_w * cur_h * 3);
187 for (dst, src) in dst.chunks_mut(stride).skip(start).take(height).zip(self.tile.chunks(cur_w * 3)) {
188 dst[..cur_w * 3].copy_from_slice(src);
192 let mut mr = MemoryReader::new_read(&self.tile[..src_len]);
193 let mut br = ByteReader::new(&mut mr);
194 for line in dst.chunks_mut(stride).skip(start).take(height) {
195 for rgb in line.chunks_mut(3).take(cur_w) {
196 let b = br.read_byte()?;
198 rgb.copy_from_slice(&self.pal[(b as usize) * 3..][..3]);
200 let c = br.read_byte()?;
201 let clr = (u16::from(b & 0x7F) << 8) | u16::from(c);
202 let r = (clr >> 10) as u8;
203 let g = ((clr >> 5) & 0x1F) as u8;
204 let b = (clr & 0x1F) as u8;
205 rgb[0] = (r << 3) | (r >> 2);
206 rgb[1] = (g << 3) | (g >> 2);
207 rgb[2] = (b << 3) | (b >> 2);
226 impl NADecoder for FSVDecoder {
227 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
228 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
229 let w = vinfo.get_width();
230 let h = vinfo.get_height();
231 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(w, h, true, BGR24_FORMAT));
232 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
236 Err(DecoderError::InvalidData)
239 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
240 let src = pkt.get_buffer();
242 validate!(src.len() > 4);
243 let mut mr = MemoryReader::new_read(&src);
244 let mut br = ByteReader::new(&mut mr);
246 let hdr0 = br.read_u16be()? as usize;
247 let hdr1 = br.read_u16be()? as usize;
248 let w = hdr0 & 0xFFF;
249 let h = hdr1 & 0xFFF;
250 let blk_w = (hdr0 >> 12) * 16 + 16;
251 let blk_h = (hdr1 >> 12) * 16 + 16;
252 validate!(w != 0 && h != 0 && blk_w != 0 && blk_h != 0);
255 let flags = br.read_byte()?;
256 self.has_pal = (flags & 1) != 0;
257 self.has_ifrm = (flags & 2) != 0;
259 let pal_sz = br.read_u16be()? as usize;
260 br.read_buf(&mut self.cbuf[..pal_sz])?;
261 self.inflate = Inflate::new();
262 if self.inflate.decompress_block(&self.cbuf[..pal_sz], &mut self.pal).is_err() {
263 return Err(DecoderError::InvalidData);
268 self.kdata.extend_from_slice(&src);
273 if self.w != w || self.h != h || self.block_w != blk_w || self.block_h != blk_h {
275 self.tile.resize(blk_w * blk_h * 3, 0);
278 self.block_w = blk_w;
279 self.block_h = blk_h;
282 let mut buf = if let Some(buffer) = self.shuf.clone_ref() {
285 let vinfo = self.info.get_properties().get_video_info().unwrap();
286 let bufinfo = alloc_video_buffer(vinfo, 0)?;
287 bufinfo.get_vbuf().unwrap()
289 let stride = buf.get_stride(0);
290 let data = buf.get_data_mut().unwrap();
291 let is_intra = if self.ver1 {
292 self.decode_v1(&mut br, data, stride)?
294 self.decode_v2(&mut br, data, stride, pkt.keyframe)?
297 if !is_intra && !self.shuf.has_last_frame() {
298 return Err(DecoderError::MissingReference);
301 if pkt.is_keyframe() {
302 self.shuf.add_keyframe(buf.clone());
304 self.shuf.add_frame(buf.clone());
306 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), NABufferType::VideoPacked(buf));
307 frm.set_frame_type(if is_intra { FrameType::I } else { FrameType::P });
310 fn flush(&mut self) {
315 impl NAOptionHandler for FSVDecoder {
316 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
317 fn set_options(&mut self, _options: &[NAOption]) { }
318 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
321 pub fn get_decoder() -> Box<dyn NADecoder + Send> {
322 Box::new(FSVDecoder::new(true))
325 pub fn get_decoder_v2() -> Box<dyn NADecoder + Send> {
326 Box::new(FSVDecoder::new(false))
331 use nihav_core::codecs::RegisteredDecoders;
332 use nihav_core::demuxers::RegisteredDemuxers;
333 use nihav_codec_support::test::dec_video::*;
334 use crate::flash_register_all_decoders;
335 use crate::flash_register_all_demuxers;
338 let mut dmx_reg = RegisteredDemuxers::new();
339 flash_register_all_demuxers(&mut dmx_reg);
340 let mut dec_reg = RegisteredDecoders::new();
341 flash_register_all_decoders(&mut dec_reg);
343 // sample: https://samples.mplayerhq.hu/FLV/flash_screen/screen.flv
344 test_decoding("flv", "flashsv", "assets/Flash/screen.flv",
345 Some(3000), &dmx_reg, &dec_reg, ExpectedTestResult::MD5Frames(vec![
346 [0xb45b899e, 0x417b17d5, 0x7bfe898b, 0x026b289f],
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 [0xc04d4d1c, 0xbb1f4b4f, 0xe9f3d85e, 0xa40aff68],
355 [0x172e5bbe, 0xe44caba3, 0x6cb2a263, 0xcb79a89a]]));
359 let mut dmx_reg = RegisteredDemuxers::new();
360 flash_register_all_demuxers(&mut dmx_reg);
361 let mut dec_reg = RegisteredDecoders::new();
362 flash_register_all_decoders(&mut dec_reg);
364 // sample created from https://samples.mplayerhq.hu/FLV/flash_screen/screen.flv by recoding
365 test_decoding("flv", "flashsv2", "assets/Flash/screen2.flv",
366 Some(4700), &dmx_reg, &dec_reg, ExpectedTestResult::MD5Frames(vec![
367 [0x55522afa, 0x9c7dd794, 0xdd67aa2e, 0x8b8c525e],
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 [0x9809efc2, 0xec5385aa, 0xb5eb9320, 0x4a47188e],
376 [0x40c77877, 0x58183722, 0x5700eb17, 0x27a00e33],
377 [0x802c2c6a, 0x3e08dd62, 0xa6c94df3, 0xc6318a6f],
378 [0x2aa70255, 0x652f0ca4, 0xe79817f9, 0x4f67e7ba],
379 [0x5cf34d91, 0xdfc54992, 0x4368180d, 0xfbe747d4],
380 [0x266d8bc4, 0x2b492ef4, 0xb42401a0, 0x23e530ec],
381 [0xa0e46b1c, 0x47d0620e, 0x0cbcb15b, 0x243e7f13]]));
385 const DEFAULT_PAL: [u8; 128 * 3] = [
386 0x00, 0x00, 0x00, 0x33, 0x33, 0x33, 0x66, 0x66, 0x66, 0x99, 0x99, 0x99,
387 0xCC, 0xCC, 0xCC, 0xFF, 0xFF, 0xFF, 0x33, 0x00, 0x00, 0x66, 0x00, 0x00,
388 0x99, 0x00, 0x00, 0xCC, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x33, 0x00,
389 0x00, 0x66, 0x00, 0x00, 0x99, 0x00, 0x00, 0xCC, 0x00, 0x00, 0xFF, 0x00,
390 0x00, 0x00, 0x33, 0x00, 0x00, 0x66, 0x00, 0x00, 0x99, 0x00, 0x00, 0xCC,
391 0x00, 0x00, 0xFF, 0x33, 0x33, 0x00, 0x66, 0x66, 0x00, 0x99, 0x99, 0x00,
392 0xCC, 0xCC, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x33, 0x33, 0x00, 0x66, 0x66,
393 0x00, 0x99, 0x99, 0x00, 0xCC, 0xCC, 0x00, 0xFF, 0xFF, 0x33, 0x00, 0x33,
394 0x66, 0x00, 0x66, 0x99, 0x00, 0x99, 0xCC, 0x00, 0xCC, 0xFF, 0x00, 0xFF,
395 0xFF, 0xFF, 0x33, 0xFF, 0xFF, 0x66, 0xFF, 0xFF, 0x99, 0xFF, 0xFF, 0xCC,
396 0xFF, 0x33, 0xFF, 0xFF, 0x66, 0xFF, 0xFF, 0x99, 0xFF, 0xFF, 0xCC, 0xFF,
397 0x33, 0xFF, 0xFF, 0x66, 0xFF, 0xFF, 0x99, 0xFF, 0xFF, 0xCC, 0xFF, 0xFF,
398 0xCC, 0xCC, 0x33, 0xCC, 0xCC, 0x66, 0xCC, 0xCC, 0x99, 0xCC, 0xCC, 0xFF,
399 0xCC, 0x33, 0xCC, 0xCC, 0x66, 0xCC, 0xCC, 0x99, 0xCC, 0xCC, 0xFF, 0xCC,
400 0x33, 0xCC, 0xCC, 0x66, 0xCC, 0xCC, 0x99, 0xCC, 0xCC, 0xFF, 0xCC, 0xCC,
401 0x99, 0x99, 0x33, 0x99, 0x99, 0x66, 0x99, 0x99, 0xCC, 0x99, 0x99, 0xFF,
402 0x99, 0x33, 0x99, 0x99, 0x66, 0x99, 0x99, 0xCC, 0x99, 0x99, 0xFF, 0x99,
403 0x33, 0x99, 0x99, 0x66, 0x99, 0x99, 0xCC, 0x99, 0x99, 0xFF, 0x99, 0x99,
404 0x66, 0x66, 0x33, 0x66, 0x66, 0x99, 0x66, 0x66, 0xCC, 0x66, 0x66, 0xFF,
405 0x66, 0x33, 0x66, 0x66, 0x99, 0x66, 0x66, 0xCC, 0x66, 0x66, 0xFF, 0x66,
406 0x33, 0x66, 0x66, 0x99, 0x66, 0x66, 0xCC, 0x66, 0x66, 0xFF, 0x66, 0x66,
407 0x33, 0x33, 0x66, 0x33, 0x33, 0x99, 0x33, 0x33, 0xCC, 0x33, 0x33, 0xFF,
408 0x33, 0x66, 0x33, 0x33, 0x99, 0x33, 0x33, 0xCC, 0x33, 0x33, 0xFF, 0x33,
409 0x66, 0x33, 0x33, 0x99, 0x33, 0x33, 0xCC, 0x33, 0x33, 0xFF, 0x33, 0x33,
410 0x00, 0x33, 0x66, 0x33, 0x66, 0x00, 0x66, 0x00, 0x33, 0x00, 0x66, 0x33,
411 0x33, 0x00, 0x66, 0x66, 0x33, 0x00, 0x33, 0x66, 0x99, 0x66, 0x99, 0x33,
412 0x99, 0x33, 0x66, 0x33, 0x99, 0x66, 0x66, 0x33, 0x99, 0x99, 0x66, 0x33,
413 0x66, 0x99, 0xCC, 0x99, 0xCC, 0x66, 0xCC, 0x66, 0x99, 0x66, 0xCC, 0x99,
414 0x99, 0x66, 0xCC, 0xCC, 0x99, 0x66, 0x99, 0xCC, 0xFF, 0xCC, 0xFF, 0x99,
415 0xFF, 0x99, 0xCC, 0x99, 0xFF, 0xCC, 0xCC, 0x99, 0xFF, 0xFF, 0xCC, 0x99,
416 0x11, 0x11, 0x11, 0x22, 0x22, 0x22, 0x44, 0x44, 0x44, 0x55, 0x55, 0x55,
417 0xAA, 0xAA, 0xAA, 0xBB, 0xBB, 0xBB, 0xDD, 0xDD, 0xDD, 0xEE, 0xEE, 0xEE
420 const BGR24_FORMAT: NAPixelFormaton = NAPixelFormaton {
421 model: ColorModel::RGB(RGBSubmodel::RGB), components: 3,
423 Some(NAPixelChromaton{
424 h_ss: 0, v_ss: 0, packed: true, depth: 8, shift: 0, comp_offs: 2, next_elem: 3 }),
425 Some(NAPixelChromaton{
426 h_ss: 0, v_ss: 0, packed: true, depth: 8, shift: 0, comp_offs: 1, next_elem: 3 }),
427 Some(NAPixelChromaton{
428 h_ss: 0, v_ss: 0, packed: true, depth: 8, shift: 0, comp_offs: 0, next_elem: 3 }),
430 elem_size: 3, be: false, alpha: false, palette: false