gdv: make demuxer set dimensions from ID if they are not provided
[nihav.git] / src / codecs / gremlinvideo.rs
CommitLineData
e120f8fd
KS
1use formats;
2use super::*;
3use io::byteio::*;
4
5struct GremlinVideoDecoder {
6 info: Rc<NACodecInfo>,
7 pal: [u8; 768],
8 frame: Vec<u8>,
9 scale_v: bool,
10 scale_h: bool,
11}
12
13struct Bits16 {
14 queue: u16,
15 fill: u8,
16}
17
18struct Bits32 {
19 queue: u32,
20 fill: u8,
21}
22
23const PREAMBLE_SIZE: usize = 4096;
24
25impl Bits16 {
26 fn new() -> Self { Bits16 { queue: 0, fill: 0 } }
27 fn read_2bits(&mut self, br: &mut ByteReader) -> ByteIOResult<u16> {
28 if self.fill == 0 {
29 self.queue |= (br.read_byte()? as u16) << self.fill;
30 self.fill += 8;
31 }
32 let res = self.queue & 0x3;
33 self.queue >>= 2;
34 self.fill -= 2;
35 Ok(res)
36 }
37}
38
39impl Bits32 {
40 fn new() -> Self { Bits32 { queue: 0, fill: 0 } }
41 fn fill(&mut self, br: &mut ByteReader) -> ByteIOResult<()> {
42 self.queue = br.read_u32le()?;
43 self.fill = 32;
44 Ok(())
45 }
46 fn read_bits(&mut self, br: &mut ByteReader, nbits: u8) -> ByteIOResult<u32> {
47 let res = self.queue & ((1 << nbits) - 1);
48 self.queue >>= nbits;
49 self.fill -= nbits;
50 if self.fill <= 16 {
51 self.queue |= (br.read_u16le()? as u32) << self.fill;
52 self.fill += 16;
53 }
54 Ok(res)
55 }
56}
57
58impl GremlinVideoDecoder {
59 fn new() -> Self {
60 let dummy_info = Rc::new(DUMMY_CODEC_INFO);
61 GremlinVideoDecoder {
62 info: dummy_info, pal: [0; 768], frame: Vec::new(),
63 scale_v: false, scale_h: false
64 }
65 }
66
67 fn lz_copy(&mut self, idx: usize, offset: isize, len: usize) -> DecoderResult<()> {
68 if idx + len > self.frame.len() { return Err(DecoderError::InvalidData); }
69 if offset == -1 {
70 let c = self.frame[idx - 1];
71 for i in 0..len { self.frame[idx + i] = c; }
72 } else if offset < 0 {
73 let start = idx - (-offset as usize);
74 for i in 0..len { self.frame[idx + i] = self.frame[start + i]; }
75 } else {
76 if idx + (offset as usize) + len > self.frame.len() { return Err(DecoderError::InvalidData); }
77 let start = idx + (offset as usize);
78 for i in 0..len { self.frame[idx + i] = self.frame[start + i]; }
79 }
80 Ok(())
81 }
82
83 fn rescale(&mut self, w: usize, h: usize, scale_v: bool, scale_h: bool) {
84 if (self.scale_v == scale_v) && (self.scale_h == scale_h) { return; }
85
86 if self.scale_h && self.scale_v {
87 for j in 0..h {
88 let y = h - j - 1;
89 for i in 0..w {
90 let x = w - i - 1;
91 self.frame[PREAMBLE_SIZE + x + y * w] = self.frame[PREAMBLE_SIZE + x/2 + (y/2) * (w/2)];
92 }
93 }
94 } else if self.scale_h {
95 for j in 0..h {
96 let y = h - j - 1;
97 for x in 0..w {
98 self.frame[PREAMBLE_SIZE + x + y * w] = self.frame[PREAMBLE_SIZE + x + (y/2) * w];
99 }
100 }
101 } else if self.scale_v {
102 for j in 0..h {
103 let y = h - j - 1;
104 for i in 0..w {
105 let x = w - i - 1;
106 self.frame[PREAMBLE_SIZE + x + y * w] = self.frame[PREAMBLE_SIZE + x/2 + y * (w/2)];
107 }
108 }
109 }
110
111 if scale_h && scale_v {
112 for y in 0..h/2 {
113 for x in 0..w/2 {
114 self.frame[PREAMBLE_SIZE + x + y * (w/2)] = self.frame[PREAMBLE_SIZE + x*2 + y*2 * w];
115 }
116 }
117 } else if scale_h {
118 for y in 0..h/2 {
119 for x in 0..w {
120 self.frame[PREAMBLE_SIZE + x + y * w] = self.frame[PREAMBLE_SIZE + x + y*2 * w];
121 }
122 }
123 } else if scale_v {
124 for y in 0..h {
125 for x in 0..w/2 {
126 self.frame[PREAMBLE_SIZE + x + y * w] = self.frame[PREAMBLE_SIZE + x*2 + y * w];
127 }
128 }
129 }
130
131 self.scale_v = scale_v;
132 self.scale_h = scale_h;
133 }
134
135 fn output_frame(&mut self, bufinfo: &mut NABufferType, w: usize, h: usize) {
136 let bufo = bufinfo.get_vbuf();
137 let mut buf = bufo.unwrap();
138 let paloff = buf.get_offset(1);
139 let stride = buf.get_stride(0);
140 let mut data = buf.get_data_mut();
141 let mut dst = data.as_mut_slice();
142 let mut sidx = PREAMBLE_SIZE;
143 let mut didx = 0;
144
145 for i in 0..768 { dst[paloff + i] = self.pal[i]; }
146 if !self.scale_v && !self.scale_h {
147 for _ in 0..h {
148 for x in 0..w { dst[didx + x] = self.frame[sidx + x]; }
149 sidx += w;
150 didx += stride;
151 }
152 } else {
153 for y in 0..h {
154 if !self.scale_v {
155 for x in 0..w { dst[didx + x] = self.frame[sidx + x]; }
156 } else {
157 for x in 0..w { dst[didx + x] = self.frame[sidx + x/2]; }
158 }
159 if !self.scale_h || ((y & 1) == 1) {
160 sidx += if !self.scale_v { w } else { w/2 };
161 }
162 didx += stride;
163 }
164 }
165 }
166
167 fn decode_method2(&mut self, br: &mut ByteReader) -> DecoderResult<()> {
168 let mut bits = Bits16::new();
169
170 let mut size = self.info.get_properties().get_video_info().unwrap().get_width() *
171 self.info.get_properties().get_video_info().unwrap().get_height();
172 let mut idx = PREAMBLE_SIZE;
173 for c in 0..256 {
174 for i in 0..16 { self.frame[c * 16 + i] = c as u8; }
175 }
176 while size > 0 {
177 let tag = bits.read_2bits(br)?;
178 if tag == 0 {
179 self.frame[idx] = br.read_byte()?;
180 size -= 1;
181 idx += 1;
182 } else if tag == 1 {
183 let b = br.read_byte()?;
184 let len = ((b & 0xF) as usize) + 3;
185 let top = (b >> 4) as isize;
186 let off = (top << 8) + (br.read_byte()? as isize) - 4096;
187 validate!(len <= size);
188 size -= len;
189 self.lz_copy(idx, off, len)?;
190 idx += len;
191 } else if tag == 2 {
192 let len = (br.read_byte()? as usize) + 2;
193 validate!(len <= size);
194 size -= len;
195 idx += len;
196 } else {
197 break;
198 }
199 }
200 Ok(())
201 }
202
203 fn decode_method5(&mut self, br: &mut ByteReader, skip: usize) -> DecoderResult<()> {
204 let mut bits = Bits16::new();
205
206 let mut size = self.info.get_properties().get_video_info().unwrap().get_width() *
207 self.info.get_properties().get_video_info().unwrap().get_height();
208 let mut idx = PREAMBLE_SIZE;
209 validate!(size >= skip);
210 size -= skip;
211 idx += skip;
212 while size > 0 {
213 let tag = bits.read_2bits(br)?;
214 if tag == 0 {
215 self.frame[idx] = br.read_byte()?;
216 size -= 1;
217 idx += 1;
218 } else if tag == 1 {
219 let b = br.read_byte()?;
220 let len = ((b & 0xF) as usize) + 3;
221 let top = (b >> 4) as isize;
222 let off = (top << 8) + (br.read_byte()? as isize) - 4096;
223 validate!(len <= size);
224 size -= len;
225 self.lz_copy(idx, off, len)?;
226 idx += len;
227 } else if tag == 2 {
228 let b = br.read_byte()?;
229 if b == 0 { break; }
230 let len: usize = if b != 0xFF { b as usize } else { br.read_u16le()? as usize };
231 validate!(len <= size);
232 size -= len;
233 idx += len;
234 } else {
235 let b = br.read_byte()?;
236 let len = ((b & 0x3) as usize) + 2;
237 let off = -((b >> 2) as isize) - 1;
238 validate!(len <= size);
239 size -= len;
240 self.lz_copy(idx, off, len)?;
241 idx += len;
242 }
243 }
244 Ok(())
245 }
246
247 fn decode_method68(&mut self, br: &mut ByteReader,
248 skip: usize, use8: bool) -> DecoderResult<()> {
249 let mut bits = Bits32::new();
250
251 let mut size = self.info.get_properties().get_video_info().unwrap().get_width() *
252 self.info.get_properties().get_video_info().unwrap().get_height();
253 let mut idx = PREAMBLE_SIZE;
254 validate!(size >= skip);
255 size -= skip;
256 idx += skip;
257 bits.fill(br)?;
258 while size > 0 {
259 let tag = bits.read_bits(br, 2)?;
260 if tag == 0 { //draw
261 let b = bits.read_bits(br, 1)?;
262 if b == 0 {
263 self.frame[idx] = br.read_byte()?;
264 size -= 1;
265 idx += 1;
266 } else {
267 let mut len: usize = 2;
268 let mut lbits = 0;
269 loop {
270 lbits += 1;
271 let val = bits.read_bits(br, lbits)?;
272 len += val as usize;
273 if val != ((1 << lbits) - 1) { break; }
274 validate!(lbits < 16);
275 }
276 validate!(len <= size);
277 for i in 0..len { self.frame[idx + i] = br.read_byte()?; }
278 size -= len;
279 idx += len;
280 }
281 } else if tag == 1 { //skip
282 let b = bits.read_bits(br, 1)?;
283 let len: usize;
284 if b == 0 {
285 len = (bits.read_bits(br, 4)? as usize) + 2;
286 } else {
287 let bb = br.read_byte()?;
288 if (bb & 0x80) == 0 {
289 len = (bb as usize) + 18;
290 } else {
291 let top = ((bb & 0x7F) as usize) << 8;
292 len = top + (br.read_byte()? as usize) + 146;
293 }
294 }
295 validate!(len <= size);
296 size -= len;
297 idx += len;
298 } else if tag == 2 {
299 let subtag = bits.read_bits(br, 2)? as usize;
300 if subtag != 3 {
301 let top = (bits.read_bits(br, 4)? as usize) << 8;
302 let offs = top + (br.read_byte()? as usize);
303 if (subtag != 0) || (offs <= 0xF80) {
304 let len = (subtag as usize) + 3;
305 self.lz_copy(idx, (offs as isize) - 4096, len)?;
306 idx += len;
307 } else {
308 if offs == 0xFFF { return Ok(()); }
309 let real_off = ((offs >> 4) & 0x7) + 1;
310 let len = ((offs & 0xF) + 2) * 2;
311 validate!(len <= size);
312 size -= len;
313 let c1 = self.frame[idx - real_off];
314 let c2 = self.frame[idx - real_off + 1];
315 for i in 0..len/2 {
316 self.frame[idx + i*2 + 0] = c1;
317 self.frame[idx + i*2 + 1] = c2;
318 }
319 idx += len;
320 }
321 } else {
322 let b = br.read_byte()?;
323 let off = ((b & 0x7F) as usize) + 1;
324 let len = if (b & 0x80) == 0 { 2 } else { 3 };
325 validate!(len <= size);
326 size -= len;
327 self.lz_copy(idx, -(off as isize), len)?;
328 idx += len;
329 }
330 } else {
331 let len: usize;
332 let off: isize;
333 if use8 {
334 let b = br.read_byte()?;
335 if (b & 0xC0) == 0xC0 {
336 len = ((b & 0x3F) as usize) + 8;
337 let q = bits.read_bits(br, 4)? as isize;
338 off = (q << 8) + (br.read_byte()? as isize) + 1;
339 } else {
340 let ofs1: isize;
341 if (b & 0x80) == 0 {
342 len = ((b >> 4) as usize) + 6;
343 ofs1 = (b & 0xF) as isize;
344 } else {
345 len = ((b & 0x3F) as usize) + 14;
346 ofs1 = bits.read_bits(br, 4)? as isize;
347 }
348 off = (ofs1 << 8) + (br.read_byte()? as isize) - 4096;
349 }
350 } else {
351 let b = br.read_byte()?;
352 if (b >> 4) == 0xF {
353 len = (br.read_byte()? as usize) + 21;
354 } else {
355 len = ((b >> 4) as usize) + 6;
356 }
357 let ofs1 = (b & 0xF) as isize;
358 off = (ofs1 << 8) + (br.read_byte()? as isize) - 4096;
359 }
360 validate!(len <= size);
361 size -= len;
362 self.lz_copy(idx, off, len)?;
363 idx += len;
364 }
365 }
366 Ok(())
367 }
368}
369
370impl NADecoder for GremlinVideoDecoder {
371 fn init(&mut self, info: Rc<NACodecInfo>) -> DecoderResult<()> {
372 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
373 let w = vinfo.get_width();
374 let h = vinfo.get_height();
375 if !vinfo.get_format().is_paletted() { return Err(DecoderError::NotImplemented); }
376 let fmt = formats::PAL8_FORMAT;
377 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(w, h, false, fmt));
378 self.info = Rc::new(NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()));
379
380 self.frame.resize(PREAMBLE_SIZE + w * h, 0);
381 for i in 0..2 {
382 for j in 0..256 {
383 for k in 0..8 {
384 self.frame[i * 2048 + j * 8 + k] = j as u8;
385 }
386 }
387 }
388 let edata = info.get_extradata().unwrap();
389 validate!(edata.len() == 768);
390 for c in 0..256 {
391 for i in 0..3 {
392 let cc = edata[c * 3 + i];
393 self.pal[c * 3 + (2 - i)] = (cc << 2) | (cc >> 4);
394 }
395 }
396 Ok(())
397 } else {
398 Err(DecoderError::InvalidData)
399 }
400 }
401 fn decode(&mut self, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
402 let src = pkt.get_buffer();
403 let mut mr = MemoryReader::new_read(&src);
404 let mut br = ByteReader::new(&mut mr);
405 let flags = br.read_u32le()?;
406 let w = self.info.get_properties().get_video_info().unwrap().get_width();
407 let h = self.info.get_properties().get_video_info().unwrap().get_height();
408
409 let cmethod = flags & 0xF;
410 let is_intra = (flags & 0x40) != 0;
411 let scale_v = (flags & 0x10) != 0;
412 let scale_h = (flags & 0x20) != 0;
413
414 self.rescale(w, h, scale_v, scale_h);
415
416 if (cmethod == 0) || (cmethod == 1) {
417 for c in 0..256 {
418 for i in 0..3 {
419 let b = br.read_byte()?;
420 self.pal[c * 3 + (2 - i)] = (b << 2) | (b >> 4);
421 }
422 }
423 if cmethod == 1 {
424 for i in PREAMBLE_SIZE..self.frame.len() { self.frame[i] = 0x00; }
425 }
426 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), NABufferType::None);
427 frm.set_keyframe(false);
428 frm.set_frame_type(FrameType::Skip);
429 return Ok(Rc::new(RefCell::new(frm)))
430 } else if cmethod == 3 {
431 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), NABufferType::None);
432 frm.set_keyframe(false);
433 frm.set_frame_type(FrameType::Skip);
434 return Ok(Rc::new(RefCell::new(frm)))
435 } else if cmethod == 2 {
436 self.decode_method2(&mut br)?;
437 } else if cmethod == 5 {
438 self.decode_method5(&mut br, (flags >> 8) as usize)?;
439 } else if cmethod == 6 {
440 self.decode_method68(&mut br, (flags >> 8) as usize, false)?;
441 } else if cmethod == 8 {
442 self.decode_method68(&mut br, (flags >> 8) as usize, true)?;
443 } else {
444 return Err(DecoderError::NotImplemented);
445 }
446
447 let bufret = alloc_video_buffer(self.info.get_properties().get_video_info().unwrap(), 0);
448 if let Err(_) = bufret { return Err(DecoderError::InvalidData); }
449 let mut bufinfo = bufret.unwrap();
450
451 self.output_frame(&mut bufinfo, w, h);
452
453 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo);
454 frm.set_keyframe(is_intra);
455 frm.set_frame_type(if is_intra { FrameType::I } else { FrameType::P });
456 Ok(Rc::new(RefCell::new(frm)))
457 }
458}
459
460pub fn get_decoder() -> Box<NADecoder> {
461 Box::new(GremlinVideoDecoder::new())
462}
463
464#[cfg(test)]
465mod test {
466 use codecs::*;
467 use demuxers::*;
468 use io::byteio::*;
469 use std::fs::File;
470
471 #[test]
472 fn test_gdv() {
473 let gdv_dmx = find_demuxer("gdv").unwrap();
474 let mut file = File::open("assets/intro1.gdv").unwrap();
475 let mut fr = FileReader::new_read(&mut file);
476 let mut br = ByteReader::new(&mut fr);
477 let mut dmx = gdv_dmx.new_demuxer(&mut br);
478 dmx.open().unwrap();
479
480 let mut decs: Vec<Option<Box<NADecoder>>> = Vec::new();
481 for i in 0..dmx.get_num_streams() {
482 let s = dmx.get_stream(i).unwrap();
483 let info = s.get_info();
484 let decfunc = find_decoder(info.get_name());
485 if !info.is_video() {
486 decs.push(None);
487 } else if let Some(df) = decfunc {
488 let mut dec = (df)();
489 dec.init(info).unwrap();
490 decs.push(Some(dec));
491 } else {
492panic!("decoder {} not found", info.get_name());
493 }
494 }
495
496 loop {
497 let pktres = dmx.get_frame();
498 if let Err(e) = pktres {
499 if e == DemuxerError::EOF { break; }
500 }
501 let pkt = pktres.unwrap();
502 let streamno = pkt.get_stream().get_id() as usize;
503 if let Some(ref mut dec) = decs[streamno] {
df14fb81
KS
504// let frm =
505dec.decode(&pkt).unwrap();
506// if pkt.get_stream().get_info().is_video() {
507// if frm.borrow().get_frame_type() != FrameType::Skip {
508// write_palppm("gdv", streamno, pkt.get_pts().unwrap(), frm);
509// }
510// }
e120f8fd
KS
511 }
512 if pkt.get_pts().unwrap() > 8 { break; }
513 }
514//panic!("end");
515 }
516}