]>
Commit | Line | Data |
---|---|---|
1ee737a4 KS |
1 | use nihav_core::muxers::*; |
2 | ||
3 | struct Y4MMuxer<'a> { | |
4 | bw: &'a mut ByteWriter<'a>, | |
5 | } | |
6 | ||
7 | impl<'a> Y4MMuxer<'a> { | |
8 | fn new(bw: &'a mut ByteWriter<'a>) -> Self { | |
9 | Self { | |
10 | bw, | |
11 | } | |
12 | } | |
13 | } | |
14 | ||
15 | fn get_format_name(fmt: NAPixelFormaton) -> MuxerResult<&'static str> { | |
16 | if fmt.model.is_yuv() && fmt.get_max_depth() == 8 { | |
17 | match fmt.components { | |
18 | 1 => Ok("mono"), | |
19 | 3 => { | |
20 | let uinfo = fmt.comp_info[1].unwrap(); | |
21 | let vinfo = fmt.comp_info[2].unwrap(); | |
22 | if uinfo.h_ss != vinfo.h_ss || uinfo.v_ss != vinfo.v_ss { | |
23 | return Err(MuxerError::UnsupportedFormat); | |
24 | } | |
25 | match (uinfo.h_ss, vinfo.v_ss) { | |
26 | (0, 0) => Ok("444"), | |
27 | (1, 0) => Ok("422"), | |
28 | (1, 1) => Ok("420"), | |
29 | (2, 0) => Ok("411"), | |
30 | _ => Err(MuxerError::UnsupportedFormat), | |
31 | } | |
32 | }, | |
33 | _ => Err(MuxerError::UnsupportedFormat), | |
34 | } | |
35 | } else { | |
36 | Err(MuxerError::UnsupportedFormat) | |
37 | } | |
38 | } | |
39 | ||
40 | impl<'a> MuxCore<'a> for Y4MMuxer<'a> { | |
41 | fn create(&mut self, strmgr: &StreamManager) -> MuxerResult<()> { | |
42 | if strmgr.get_num_streams() != 1 { | |
43 | return Err(MuxerError::InvalidArgument); | |
44 | } | |
45 | let vstr = strmgr.get_stream(0).unwrap(); | |
46 | if vstr.get_media_type() != StreamType::Video { | |
47 | return Err(MuxerError::UnsupportedFormat); | |
48 | } | |
49 | let info = vstr.get_info(); | |
50 | let vinfo = info.get_properties().get_video_info().unwrap(); | |
51 | self.bw.write_buf(format!("YUV4MPEG2 W{} H{} F{}:{} C{}\n", vinfo.width, vinfo.height, vstr.tb_den, vstr.tb_num, get_format_name(vinfo.format)?).as_bytes())?; | |
52 | ||
53 | Ok(()) | |
54 | } | |
55 | fn mux_frame(&mut self, _strmgr: &StreamManager, pkt: NAPacket) -> MuxerResult<()> { | |
56 | if self.bw.tell() == 0 { | |
57 | return Err(MuxerError::NotCreated); | |
58 | } | |
59 | let src = pkt.get_buffer(); | |
60 | self.bw.write_buf(b"FRAME\n")?; | |
61 | self.bw.write_buf(&src)?; | |
62 | Ok(()) | |
63 | } | |
64 | fn flush(&mut self) -> MuxerResult<()> { | |
65 | Ok(()) | |
66 | } | |
67 | fn end(&mut self) -> MuxerResult<()> { | |
68 | Ok(()) | |
69 | } | |
70 | } | |
71 | ||
72 | impl<'a> NAOptionHandler for Y4MMuxer<'a> { | |
73 | fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] } | |
74 | fn set_options(&mut self, _options: &[NAOption]) { } | |
75 | fn query_option_value(&self, _name: &str) -> Option<NAValue> { None } | |
76 | } | |
77 | ||
78 | pub struct Y4MMuxerCreator {} | |
79 | ||
80 | impl MuxerCreator for Y4MMuxerCreator { | |
81 | fn new_muxer<'a>(&self, bw: &'a mut ByteWriter<'a>) -> Box<dyn MuxCore<'a> + 'a> { | |
82 | Box::new(Y4MMuxer::new(bw)) | |
83 | } | |
84 | fn get_name(&self) -> &'static str { "yuv4mpeg" } | |
85 | fn get_capabilities(&self) -> MuxerCapabilities { MuxerCapabilities::SingleVideo("rawvideo") } | |
86 | } | |
87 | ||
88 | #[cfg(test)] | |
89 | mod test { | |
90 | use nihav_core::codecs::*; | |
91 | use nihav_core::demuxers::*; | |
92 | use nihav_core::muxers::*; | |
93 | use nihav_codec_support::test::enc_video::*; | |
94 | use crate::*; | |
95 | ||
96 | #[test] | |
97 | fn test_y4m_muxer() { | |
98 | let mut dmx_reg = RegisteredDemuxers::new(); | |
99 | generic_register_all_demuxers(&mut dmx_reg); | |
100 | // sample: self-created with avconv | |
101 | let dec_config = DecoderTestParams { | |
102 | demuxer: "yuv4mpeg", | |
103 | in_name: "assets/Misc/test.y4m", | |
104 | limit: None, | |
105 | stream_type: StreamType::None, | |
106 | dmx_reg, dec_reg: RegisteredDecoders::new(), | |
107 | }; | |
108 | let mut mux_reg = RegisteredMuxers::new(); | |
109 | generic_register_all_muxers(&mut mux_reg); | |
110 | /*let enc_config = EncoderTestParams { | |
111 | muxer: "yuv4mpeg", | |
112 | enc_name: "", | |
113 | out_name: "muxed.y4m", | |
114 | mux_reg, enc_reg: RegisteredEncoders::new(), | |
115 | }; | |
116 | test_remuxing(&dec_config, &enc_config);*/ | |
117 | test_remuxing_md5(&dec_config, "yuv4mpeg", &mux_reg, | |
118 | [0x7586c1c5, 0x388209b8, 0xe08af8f8, 0x4b6b96c7]); | |
119 | } | |
120 | } |