]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | known bugs and limitations: | |
3 | * wrong slice boundary filtering | |
4 | * not fully correct deblock strength selection for P/B-macroblocks | |
5 | * scaling lists for 4x4 blocks | |
6 | */ | |
7 | use std::sync::{Arc, RwLock}; | |
8 | ||
9 | use nihav_core::codecs::*; | |
10 | use nihav_core::io::byteio::*; | |
11 | use nihav_core::io::bitreader::*; | |
12 | use nihav_core::io::intcode::*; | |
13 | use nihav_codec_support::codecs::{MV, ZERO_MV}; | |
14 | ||
15 | pub type Shareable<T> = Arc<RwLock<T>>; | |
16 | ||
17 | mod types; | |
18 | pub use types::*; | |
19 | mod pic_ref; | |
20 | pub use pic_ref::*; | |
21 | #[allow(clippy::identity_op)] | |
22 | #[allow(clippy::erasing_op)] | |
23 | #[allow(clippy::many_single_char_names)] | |
24 | #[allow(clippy::range_plus_one)] | |
25 | mod dsp; | |
26 | use dsp::*; | |
27 | mod cabac; | |
28 | use cabac::*; | |
29 | mod cabac_coder; | |
30 | use cabac_coder::*; | |
31 | mod cavlc; | |
32 | use cavlc::*; | |
33 | mod loopfilter; | |
34 | use loopfilter::*; | |
35 | mod mb_recon; | |
36 | use mb_recon::*; | |
37 | mod sets; | |
38 | use sets::*; | |
39 | mod slice; | |
40 | use slice::*; | |
41 | ||
42 | mod decoder_st; | |
43 | pub use decoder_st::*; | |
44 | mod dispatch; | |
45 | mod decoder_mt; | |
46 | pub use decoder_mt::*; | |
47 | ||
48 | trait ReadUE { | |
49 | fn read_ue(&mut self) -> DecoderResult<u32>; | |
50 | fn read_te(&mut self, range: u32) -> DecoderResult<u32>; | |
51 | fn read_ue_lim(&mut self, max_val: u32) -> DecoderResult<u32> { | |
52 | let val = self.read_ue()?; | |
53 | validate!(val <= max_val); | |
54 | Ok(val) | |
55 | } | |
56 | fn read_se(&mut self) -> DecoderResult<i32> { | |
57 | let val = self.read_ue()?; | |
58 | if (val & 1) != 0 { | |
59 | Ok (((val >> 1) as i32) + 1) | |
60 | } else { | |
61 | Ok (-((val >> 1) as i32)) | |
62 | } | |
63 | } | |
64 | } | |
65 | ||
66 | impl<'a> ReadUE for BitReader<'a> { | |
67 | fn read_ue(&mut self) -> DecoderResult<u32> { | |
68 | Ok(self.read_code(UintCodeType::GammaP)? - 1) | |
69 | } | |
70 | fn read_te(&mut self, range: u32) -> DecoderResult<u32> { | |
71 | if range == 1 { | |
72 | if self.read_bool()? { | |
73 | Ok(0) | |
74 | } else { | |
75 | Ok(1) | |
76 | } | |
77 | } else { | |
78 | let val = self.read_ue()?; | |
79 | validate!(val <= range); | |
80 | Ok(val) | |
81 | } | |
82 | } | |
83 | } | |
84 | ||
85 | #[derive(Clone,Copy)] | |
86 | pub struct Coeff8x8 { | |
87 | pub coeffs: [i16; 64], | |
88 | } | |
89 | ||
90 | impl Coeff8x8 { | |
91 | fn clear(&mut self) { | |
92 | self.coeffs = [0; 64]; | |
93 | } | |
94 | } | |
95 | ||
96 | impl Default for Coeff8x8 { | |
97 | fn default() -> Self { | |
98 | Self { | |
99 | coeffs: [0; 64], | |
100 | } | |
101 | } | |
102 | } | |
103 | ||
104 | #[derive(Clone,Copy,Default)] | |
105 | pub struct CurrentMBInfo { | |
106 | pub mb_type: MBType, | |
107 | pub sub_mb_type: [SubMBType; 4], | |
108 | pub ipred: [IntraPredMode; 16], | |
109 | pub chroma_ipred: u8, | |
110 | pub luma_ipred: [u8; 16], | |
111 | pub mv_l0: [MV; 16], | |
112 | pub ref_l0: [PicRef; 4], | |
113 | pub mv_l1: [MV; 16], | |
114 | pub ref_l1: [PicRef; 4], | |
115 | pub qp_y: u8, | |
116 | pub cbpy: u8, | |
117 | pub cbpc: u8, | |
118 | pub coeffs: [[i16; 16]; 25], | |
119 | pub coeffs8x8: [Coeff8x8; 4], | |
120 | pub chroma_dc: [[i16; 4]; 2], | |
121 | pub coded: [bool; 25], | |
122 | pub transform_size_8x8: bool, | |
123 | } | |
124 | ||
125 | impl CurrentMBInfo { | |
126 | fn clear_coeffs8x8(&mut self) { | |
127 | for c in self.coeffs8x8.iter_mut() { | |
128 | c.clear(); | |
129 | } | |
130 | } | |
131 | fn can_have_8x8_tx(&self, inference_flag: bool) -> bool { | |
132 | match self.mb_type { | |
133 | MBType::Intra4x4 | MBType::Intra8x8 | MBType::Intra16x16(_, _, _) | MBType::PCM => false, | |
134 | MBType::P8x8 | MBType::P8x8Ref0 | MBType::B8x8 => { | |
135 | for &sub_id in self.sub_mb_type.iter() { | |
136 | match sub_id { | |
137 | SubMBType::P8x8 | | |
138 | SubMBType::B8x8(_) | |
139 | => {}, | |
140 | SubMBType::Direct8x8 | |
141 | => if !inference_flag { return false; }, | |
142 | _ => return false, | |
143 | }; | |
144 | } | |
145 | true | |
146 | }, | |
147 | MBType::Direct => inference_flag, | |
148 | _ => true, | |
149 | } | |
150 | } | |
151 | } | |
152 | ||
153 | fn get_long_term_id(is_idr: bool, slice_hdr: &SliceHeader) -> Option<usize> { | |
154 | if is_idr && !slice_hdr.long_term_reference { | |
155 | None | |
156 | } else { | |
157 | let marking = &slice_hdr.adaptive_ref_pic_marking; | |
158 | for (&op, &arg) in marking.memory_management_control_op.iter().zip(marking.operation_arg.iter()).take(marking.num_ops) { | |
159 | if op == 6 { | |
160 | return Some(arg as usize); | |
161 | } | |
162 | } | |
163 | None | |
164 | } | |
165 | } | |
166 | ||
167 | fn unescape_nal(src: &[u8], dst: &mut Vec<u8>) -> usize { | |
168 | let mut off = 0; | |
169 | let mut zrun = 0; | |
170 | dst.clear(); | |
171 | dst.reserve(src.len()); | |
172 | while off < src.len() { | |
173 | dst.push(src[off]); | |
174 | if src[off] != 0 { | |
175 | zrun = 0; | |
176 | } else { | |
177 | zrun += 1; | |
178 | if zrun == 2 && off + 1 < src.len() && src[off + 1] == 0x03 { | |
179 | zrun = 0; | |
180 | off += 1; | |
181 | } | |
182 | if zrun >= 3 && off + 1 < src.len() && src[off + 1] == 0x01 { | |
183 | off -= 3; | |
184 | dst.truncate(off); | |
185 | break; | |
186 | } | |
187 | } | |
188 | off += 1; | |
189 | } | |
190 | off | |
191 | } | |
192 | ||
193 | const DEBLOCK_SKIP_OPTION: &str = "skip_deblock"; | |
194 | ||
195 | const DECODER_OPTIONS: &[NAOptionDefinition] = &[ | |
196 | NAOptionDefinition { | |
197 | name: FRAME_SKIP_OPTION, description: FRAME_SKIP_OPTION_DESC, | |
198 | opt_type: NAOptionDefinitionType::Bool }, | |
199 | NAOptionDefinition { | |
200 | name: DEBLOCK_SKIP_OPTION, description: "Loop filter skipping mode", | |
201 | opt_type: NAOptionDefinitionType::String(Some(&[ | |
202 | FRAME_SKIP_OPTION_VAL_NONE, | |
203 | FRAME_SKIP_OPTION_VAL_KEYFRAME, | |
204 | FRAME_SKIP_OPTION_VAL_INTRA | |
205 | ])) }, | |
206 | ]; | |
207 | ||
208 | #[cfg(test)] | |
209 | mod test { | |
210 | use nihav_core::codecs::*; | |
211 | use nihav_core::demuxers::RegisteredDemuxers; | |
212 | use nihav_codec_support::test::dec_video::*; | |
213 | use crate::*; | |
214 | use nihav_commonfmt::generic_register_all_demuxers; | |
215 | ||
216 | // samples if not specified otherwise come from H.264 conformance suite | |
217 | mod raw_demux; | |
218 | mod conformance; | |
219 | mod conformance_mt; | |
220 | use self::raw_demux::RawH264DemuxerCreator; | |
221 | ||
222 | #[test] | |
223 | fn test_h264_perframe() { | |
224 | let mut dmx_reg = RegisteredDemuxers::new(); | |
225 | dmx_reg.add_demuxer(&RawH264DemuxerCreator{}); | |
226 | generic_register_all_demuxers(&mut dmx_reg); | |
227 | let mut dec_reg = RegisteredDecoders::new(); | |
228 | itu_register_all_decoders(&mut dec_reg); | |
229 | ||
230 | test_decoding("rawh264", "h264", | |
231 | "assets/ITU/h264-conformance/CABAST3_Sony_E.jsv", | |
232 | None, &dmx_reg, &dec_reg, ExpectedTestResult::MD5Frames(vec![ | |
233 | [0xb5e5e368, 0x6ac59bfc, 0x82e35b7b, 0xbed17b81], | |
234 | [0x8343b34d, 0x0de80ae9, 0xe9c08cc9, 0x05161d82], | |
235 | [0x26e08b9b, 0x84949759, 0x71622124, 0x9bfff254], | |
236 | [0x940c38bc, 0x559fb990, 0x2b82a7ca, 0x3543188a], | |
237 | [0x60d7544d, 0x2fc8cc23, 0x4acac90f, 0x44c2a91c], | |
238 | [0x68d86265, 0x15fc15b9, 0xe4946d83, 0x39d9584d], | |
239 | [0xaed8e194, 0xa24b3a8a, 0xbed9085d, 0x05d68293], | |
240 | [0x1cddffac, 0x0ce9d209, 0xc4090b8a, 0xc3008856], | |
241 | [0x42ee0e5e, 0x4c1c3b64, 0xd91cc00b, 0x88be4b15], | |
242 | [0x19a70aa8, 0xd8bc987d, 0x51c04849, 0x71191523], | |
243 | [0x74532da6, 0xecb92919, 0xd39cb150, 0x9ca9933d], | |
244 | [0x0444b315, 0x2ddfb91a, 0x1e21ce06, 0x0c8613e6], | |
245 | [0xce209363, 0xf8d8331f, 0x72e0102f, 0x88de3a97], | |
246 | [0xdbcfa40a, 0x7eed5940, 0xa5c53a66, 0xdfcd3cea], | |
247 | [0x00796b14, 0x58f16117, 0xb6a5efd1, 0xfb129acd], | |
248 | [0x7673f569, 0xfccfb96a, 0x1f614c82, 0xf62ea376], | |
249 | [0x8669d98b, 0x9fdf4e7d, 0xa4083a7f, 0x9b66d296], | |
250 | [0xf0537976, 0x924229ab, 0xd0f4612f, 0xad4b614e], | |
251 | [0xbde82067, 0x6cf23a0c, 0xdd29e64d, 0xcaa72ff3], | |
252 | [0xcfcb544a, 0x1f1a81b0, 0x2217108c, 0x4888d5ef], | |
253 | [0x3369f874, 0x6a6dde75, 0x46d64780, 0xbf6ced32], | |
254 | [0x253a1f45, 0x85954311, 0x983dbabe, 0x658f4ce3], | |
255 | [0xec97b332, 0xa17b26d0, 0xbead22af, 0xa6bd7d8e], | |
256 | [0x5673d973, 0x78528036, 0xabfe5e13, 0xdcedfb26], | |
257 | [0xd6110fa9, 0x532d6a30, 0xb7f0aa7c, 0xae7b544b]])); | |
258 | } | |
259 | ||
260 | // mostly static music video downloaded with youtube-dl | |
261 | #[test] | |
262 | fn test_h264_real1() { | |
263 | let mut dmx_reg = RegisteredDemuxers::new(); | |
264 | dmx_reg.add_demuxer(&RawH264DemuxerCreator{}); | |
265 | generic_register_all_demuxers(&mut dmx_reg); | |
266 | let mut dec_reg = RegisteredDecoders::new(); | |
267 | itu_register_all_decoders(&mut dec_reg); | |
268 | ||
269 | test_decoding("mov", "h264", "assets/ITU/1.mp4", | |
270 | Some(60), &dmx_reg, &dec_reg, | |
271 | ExpectedTestResult::MD5Frames(vec![ | |
272 | [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970], | |
273 | [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970], | |
274 | [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970], | |
275 | [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970], | |
276 | [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970], | |
277 | [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970], | |
278 | [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970], | |
279 | [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970], | |
280 | [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970], | |
281 | [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970], | |
282 | [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970], | |
283 | [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970], | |
284 | [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970], | |
285 | [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970], | |
286 | [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970], | |
287 | [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970], | |
288 | [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970], | |
289 | [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970], | |
290 | [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970], | |
291 | [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970], | |
292 | [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970], | |
293 | [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970], | |
294 | [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970], | |
295 | [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970], | |
296 | [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970], | |
297 | [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970], | |
298 | [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970], | |
299 | [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970], | |
300 | [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970], | |
301 | [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970], | |
302 | [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970], | |
303 | [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970], | |
304 | [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970], | |
305 | [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970], | |
306 | [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970], | |
307 | [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970], | |
308 | [0x9dbac04a, 0xc49ca8c1, 0x09bb9182, 0xc7928970], | |
309 | [0xc54f1b6e, 0xaba56a71, 0x8b45132b, 0x3c8bde7f], | |
310 | [0xe2742374, 0x7b9d6fa6, 0xd57eb3bb, 0x42986664], | |
311 | [0xa5ebdc2e, 0x9753a46a, 0x631c6359, 0x861ae0e3], | |
312 | [0x4d2c8769, 0xb9e15141, 0x03274d1f, 0xc15a3733], | |
313 | [0x17ebec8f, 0xe417571e, 0x75eb2559, 0x2f9b882b], | |
314 | [0x148e8c97, 0x778f92ba, 0x93646539, 0xeebe643a], | |
315 | [0xc6770caa, 0x1ac11a57, 0x1388a550, 0x2347758e], | |
316 | [0x91eb3ae4, 0xaf664462, 0x858d344a, 0xda3baa79], | |
317 | [0x4de79514, 0x3597aff0, 0x53e1a22f, 0x7875aa4c], | |
318 | [0xd5afcf7c, 0xa0f4ce82, 0x21a70eb2, 0x3911cde1], | |
319 | [0x9efa2a08, 0x29019ca6, 0xaba90890, 0xfb982857], | |
320 | [0xc5755e20, 0x4c66cb54, 0x1194812e, 0x11a9d940], | |
321 | [0xfd131bbb, 0x0acefb02, 0x6c79b7ab, 0x35bcdd26], | |
322 | [0xad159db0, 0xfa65ced2, 0xf77e2b22, 0x9e6283a8], | |
323 | [0xba2059e3, 0xc9f1e5e7, 0x7ea5fbcb, 0xf48d4fc3], | |
324 | [0xbe794078, 0x64d69f9b, 0x7b6355c5, 0x7dfb5b0f], | |
325 | [0x6031b77b, 0x712f42fd, 0x30d423df, 0x740e488c], | |
326 | [0xcc475484, 0x30a664fc, 0x227a9725, 0x4b2bfb18], | |
327 | [0x44bef2ea, 0xaf1e69e8, 0x832d94a8, 0xffb22712], | |
328 | [0xe9471e3d, 0x103de80f, 0xdc44136f, 0x67dacaa8], | |
329 | [0x4df3823d, 0xf6486ca9, 0x016f3114, 0x1c2d0b42], | |
330 | [0x1171666b, 0x08ca0ced, 0x98719757, 0xbd6b4a86], | |
331 | [0x9d2fc556, 0x5569fbbd, 0x0ebf629f, 0xd4fdc3b5], | |
332 | [0x27dbd3c3, 0x803f0230, 0x13f2ff1b, 0xb661b622]])); | |
333 | } | |
334 | // a sample downloaded from gfycat.com | |
335 | #[test] | |
336 | fn test_h264_real2() { | |
337 | let mut dmx_reg = RegisteredDemuxers::new(); | |
338 | dmx_reg.add_demuxer(&RawH264DemuxerCreator{}); | |
339 | generic_register_all_demuxers(&mut dmx_reg); | |
340 | let mut dec_reg = RegisteredDecoders::new(); | |
341 | itu_register_all_decoders(&mut dec_reg); | |
342 | test_decoding("mov", "h264", "assets/ITU/DimpledSpanishCuckoo-mobile.mp4", | |
343 | Some(10), &dmx_reg, &dec_reg, | |
344 | ExpectedTestResult::MD5Frames(vec![ | |
345 | [0x674c6d60, 0xc7ab918d, 0x9db1beaf, 0xda9f2456], | |
346 | [0x6a935350, 0x3d463ab2, 0xa3ab3c53, 0x97eb896b], | |
347 | [0xf6c60411, 0x19ea2c49, 0x3512371a, 0xce6cb26a], | |
348 | [0xc87afeaa, 0x79899908, 0x152e6320, 0xe689827f], | |
349 | [0xa3d829e3, 0xb404dd32, 0x11983613, 0xbdf10ee6], | |
350 | [0x2440ea01, 0x5b9d7fc7, 0x4fa5632b, 0xd2d76090], | |
351 | [0xd80e8bf9, 0xe9190ab7, 0x2be8fa38, 0xb94182e8], | |
352 | [0x50b9fd9a, 0x64393126, 0xd03162ec, 0xfb54172a], | |
353 | [0x80d1f58f, 0x12e454c0, 0x2140ca5c, 0xe19350ba], | |
354 | [0x26078d38, 0xf6a59d57, 0xcd14eaf8, 0x8eb08259], | |
355 | [0x31494337, 0x6f8d3f52, 0x4bc9ff92, 0x0c601b1c]])); | |
356 | } | |
357 | #[test] | |
358 | fn test_h264_mt_perframe() { | |
359 | let mut dmx_reg = RegisteredDemuxers::new(); | |
360 | dmx_reg.add_demuxer(&RawH264DemuxerCreator{}); | |
361 | generic_register_all_demuxers(&mut dmx_reg); | |
362 | let mut dec_reg = RegisteredMTDecoders::new(); | |
363 | itu_register_all_mt_decoders(&mut dec_reg); | |
364 | ||
365 | test_mt_decoding("rawh264", "h264", | |
366 | "assets/ITU/h264-conformance/CABAST3_Sony_E.jsv", | |
367 | None, &dmx_reg, &dec_reg, ExpectedTestResult::MD5Frames(vec![ | |
368 | [0xb5e5e368, 0x6ac59bfc, 0x82e35b7b, 0xbed17b81], | |
369 | [0x940c38bc, 0x559fb990, 0x2b82a7ca, 0x3543188a], | |
370 | [0x60d7544d, 0x2fc8cc23, 0x4acac90f, 0x44c2a91c], | |
371 | [0x8343b34d, 0x0de80ae9, 0xe9c08cc9, 0x05161d82], | |
372 | [0xaed8e194, 0xa24b3a8a, 0xbed9085d, 0x05d68293], | |
373 | [0x1cddffac, 0x0ce9d209, 0xc4090b8a, 0xc3008856], | |
374 | [0x26e08b9b, 0x84949759, 0x71622124, 0x9bfff254], | |
375 | [0x19a70aa8, 0xd8bc987d, 0x51c04849, 0x71191523], | |
376 | [0x74532da6, 0xecb92919, 0xd39cb150, 0x9ca9933d], | |
377 | [0x68d86265, 0x15fc15b9, 0xe4946d83, 0x39d9584d], | |
378 | [0xce209363, 0xf8d8331f, 0x72e0102f, 0x88de3a97], | |
379 | [0xdbcfa40a, 0x7eed5940, 0xa5c53a66, 0xdfcd3cea], | |
380 | [0x42ee0e5e, 0x4c1c3b64, 0xd91cc00b, 0x88be4b15], | |
381 | [0x7673f569, 0xfccfb96a, 0x1f614c82, 0xf62ea376], | |
382 | [0x8669d98b, 0x9fdf4e7d, 0xa4083a7f, 0x9b66d296], | |
383 | [0x0444b315, 0x2ddfb91a, 0x1e21ce06, 0x0c8613e6], | |
384 | [0xbde82067, 0x6cf23a0c, 0xdd29e64d, 0xcaa72ff3], | |
385 | [0xcfcb544a, 0x1f1a81b0, 0x2217108c, 0x4888d5ef], | |
386 | [0x00796b14, 0x58f16117, 0xb6a5efd1, 0xfb129acd], | |
387 | [0x253a1f45, 0x85954311, 0x983dbabe, 0x658f4ce3], | |
388 | [0xec97b332, 0xa17b26d0, 0xbead22af, 0xa6bd7d8e], | |
389 | [0xf0537976, 0x924229ab, 0xd0f4612f, 0xad4b614e], | |
390 | [0x5673d973, 0x78528036, 0xabfe5e13, 0xdcedfb26], | |
391 | [0xd6110fa9, 0x532d6a30, 0xb7f0aa7c, 0xae7b544b], | |
392 | [0x3369f874, 0x6a6dde75, 0x46d64780, 0xbf6ced32]])); | |
393 | } | |
394 | // a sample downloaded from gfycat.com | |
395 | #[test] | |
396 | fn test_h264_mt_real2() { | |
397 | let mut dmx_reg = RegisteredDemuxers::new(); | |
398 | dmx_reg.add_demuxer(&RawH264DemuxerCreator{}); | |
399 | generic_register_all_demuxers(&mut dmx_reg); | |
400 | let mut dec_reg = RegisteredMTDecoders::new(); | |
401 | itu_register_all_mt_decoders(&mut dec_reg); | |
402 | test_mt_decoding("mov", "h264", "assets/ITU/DimpledSpanishCuckoo-mobile.mp4", | |
403 | Some(10), &dmx_reg, &dec_reg, | |
404 | ExpectedTestResult::MD5Frames(vec![ | |
405 | [0x674c6d60, 0xc7ab918d, 0x9db1beaf, 0xda9f2456], | |
406 | [0x6a935350, 0x3d463ab2, 0xa3ab3c53, 0x97eb896b], | |
407 | [0xa3d829e3, 0xb404dd32, 0x11983613, 0xbdf10ee6], | |
408 | [0xc87afeaa, 0x79899908, 0x152e6320, 0xe689827f], | |
409 | [0x2440ea01, 0x5b9d7fc7, 0x4fa5632b, 0xd2d76090], | |
410 | [0xf6c60411, 0x19ea2c49, 0x3512371a, 0xce6cb26a], | |
411 | [0x50b9fd9a, 0x64393126, 0xd03162ec, 0xfb54172a], | |
412 | [0xd80e8bf9, 0xe9190ab7, 0x2be8fa38, 0xb94182e8], | |
413 | [0x26078d38, 0xf6a59d57, 0xcd14eaf8, 0x8eb08259], | |
414 | [0x80d1f58f, 0x12e454c0, 0x2140ca5c, 0xe19350ba], | |
415 | [0x31494337, 0x6f8d3f52, 0x4bc9ff92, 0x0c601b1c]])); | |
416 | } | |
417 | } | |
418 | ||
419 | pub const I4X4_SCAN: [(u8, u8); 16] = [ | |
420 | (0,0), (1,0), (0,1), (1,1), (2,0), (3,0), (2,1), (3,1), | |
421 | (0,2), (1,2), (0,3), (1,3), (2,2), (3,2), (2,3), (3,3) | |
422 | ]; |