]> git.nihav.org Git - nihav.git/blame_incremental - nihav-commonfmt/src/codecs/rawvideo.rs
add YUV4MPEG muxer
[nihav.git] / nihav-commonfmt / src / codecs / rawvideo.rs
... / ...
CommitLineData
1use nihav_core::codecs::*;
2
3struct RawDecoder {
4 info: NACodecInfoRef,
5}
6
7impl RawDecoder {
8 fn new() -> Self {
9 Self {
10 info: NACodecInfo::new_dummy(),
11 }
12 }
13}
14
15impl 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
83impl 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
89pub fn get_decoder() -> Box<dyn NADecoder + Send> {
90 Box::new(RawDecoder::new())
91}
92
93#[cfg(test)]
94mod 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}