]>
Commit | Line | Data |
---|---|---|
1 | use nihav_core::codecs::*; | |
2 | ||
3 | struct RawDecoder { | |
4 | info: NACodecInfoRef, | |
5 | } | |
6 | ||
7 | impl RawDecoder { | |
8 | fn new() -> Self { | |
9 | Self { | |
10 | info: NACodecInfo::new_dummy(), | |
11 | } | |
12 | } | |
13 | } | |
14 | ||
15 | impl NADecoder for RawDecoder { | |
16 | fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> { | |
17 | if let NACodecTypeInfo::Video(_vinfo) = info.get_properties() { | |
18 | self.info = info.clone(); | |
19 | Ok(()) | |
20 | } else { | |
21 | Err(DecoderError::InvalidData) | |
22 | } | |
23 | } | |
24 | fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> { | |
25 | if let NACodecTypeInfo::Video(ref vinfo) = self.info.get_properties() { | |
26 | let src = pkt.get_buffer(); | |
27 | let width = vinfo.width; | |
28 | let height = vinfo.height; | |
29 | let ncomp = vinfo.format.components as usize; | |
30 | let buf = if vinfo.format.is_unpacked() && vinfo.format.get_max_depth() == 8 { | |
31 | let mut offs = vec![0; ncomp]; | |
32 | let mut strides = Vec::with_capacity(ncomp); | |
33 | let mut sizes = Vec::with_capacity(ncomp); | |
34 | for chr in vinfo.format.comp_info[..ncomp].iter() { | |
35 | if let Some(chromaton) = chr { | |
36 | let stride = chromaton.get_linesize(width); | |
37 | let size = stride * chromaton.get_height(height); | |
38 | sizes.push(size); | |
39 | strides.push(stride); | |
40 | } else { | |
41 | return Err(DecoderError::InvalidData); | |
42 | } | |
43 | } | |
44 | let mut off = 0; | |
45 | for i in 0..ncomp { | |
46 | for (cno, chr) in vinfo.format.comp_info[..ncomp].iter().enumerate() { | |
47 | if let Some(chromaton) = chr { | |
48 | let comp_off = chromaton.comp_offs as usize; | |
49 | validate!(comp_off < ncomp); | |
50 | if comp_off != i { | |
51 | continue; | |
52 | } | |
53 | offs[cno] = off; | |
54 | off += sizes[i]; | |
55 | } | |
56 | } | |
57 | } | |
58 | validate!(off == src.len()); | |
59 | ||
60 | NABufferType::Video(NAVideoBuffer::from_raw_parts(*vinfo, src, offs, strides).into_ref()) | |
61 | } else { | |
62 | let esize = vinfo.format.elem_size as usize; | |
63 | let ychr = vinfo.format.get_chromaton(0).unwrap(); | |
64 | let ystep = if ychr.next_elem != 0 { ychr.next_elem as usize } else { esize }; | |
65 | let stride = (width * esize + ystep - 1) / ystep; | |
66 | let offs = vec![0]; | |
67 | let strides = vec![stride]; | |
68 | NABufferType::VideoPacked(NAVideoBuffer::from_raw_parts(*vinfo, src, offs, strides).into_ref()) | |
69 | }; | |
70 | ||
71 | let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), buf); | |
72 | frm.set_keyframe(true); | |
73 | frm.set_frame_type(FrameType::I); | |
74 | Ok(frm.into_ref()) | |
75 | } else { | |
76 | Err(DecoderError::Bug) | |
77 | } | |
78 | } | |
79 | fn flush(&mut self) {} | |
80 | } | |
81 | ||
82 | ||
83 | impl NAOptionHandler for RawDecoder { | |
84 | fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] } | |
85 | fn set_options(&mut self, _options: &[NAOption]) { } | |
86 | fn query_option_value(&self, _name: &str) -> Option<NAValue> { None } | |
87 | } | |
88 | ||
89 | pub fn get_decoder() -> Box<dyn NADecoder + Send> { | |
90 | Box::new(RawDecoder::new()) | |
91 | } | |
92 | ||
93 | #[cfg(test)] | |
94 | mod test { | |
95 | use nihav_core::codecs::RegisteredDecoders; | |
96 | use nihav_core::demuxers::RegisteredDemuxers; | |
97 | use nihav_codec_support::test::dec_video::*; | |
98 | use crate::generic_register_all_decoders; | |
99 | use crate::generic_register_all_demuxers; | |
100 | #[test] | |
101 | fn test_rawvideo() { | |
102 | let mut dmx_reg = RegisteredDemuxers::new(); | |
103 | generic_register_all_demuxers(&mut dmx_reg); | |
104 | let mut dec_reg = RegisteredDecoders::new(); | |
105 | generic_register_all_decoders(&mut dec_reg); | |
106 | // sample: self-created with avconv | |
107 | test_decoding("yuv4mpeg", "rawvideo", "assets/Misc/test.y4m", None, &dmx_reg, | |
108 | &dec_reg, ExpectedTestResult::MD5Frames(vec![ | |
109 | [0xd58326b0, 0xdbfc1dcc, 0x6d66a04c, 0x08a21bbb], | |
110 | [0x9b2cb5c5, 0x69b5f261, 0xcaccaaaf, 0xff2a807d]])); | |
111 | } | |
112 | } |