1use std::rc::Rc;
6
7use anyhow::anyhow;
8use anyhow::Context;
9use libva::Display;
10use libva::Picture as VaPicture;
11use libva::SegmentParameterVP9;
12use libva::SurfaceMemoryDescriptor;
13
14use crate::backend::vaapi::decoder::va_surface_id;
15use crate::backend::vaapi::decoder::PoolCreationMode;
16use crate::backend::vaapi::decoder::VaStreamInfo;
17use crate::backend::vaapi::decoder::VaapiBackend;
18use crate::backend::vaapi::decoder::VaapiPicture;
19use crate::codec::vp9::parser::BitDepth;
20use crate::codec::vp9::parser::Header;
21use crate::codec::vp9::parser::Profile;
22use crate::codec::vp9::parser::ALTREF_FRAME;
23use crate::codec::vp9::parser::GOLDEN_FRAME;
24use crate::codec::vp9::parser::LAST_FRAME;
25use crate::codec::vp9::parser::MAX_SEGMENTS;
26use crate::codec::vp9::parser::NUM_REF_FRAMES;
27use crate::decoder::stateless::vp9::Segmentation;
28use crate::decoder::stateless::vp9::StatelessVp9DecoderBackend;
29use crate::decoder::stateless::vp9::Vp9;
30use crate::decoder::stateless::NewPictureError;
31use crate::decoder::stateless::NewPictureResult;
32use crate::decoder::stateless::NewStatelessDecoderError;
33use crate::decoder::stateless::StatelessBackendResult;
34use crate::decoder::stateless::StatelessDecoder;
35use crate::decoder::stateless::StatelessDecoderBackendPicture;
36use crate::decoder::BlockingMode;
37
38const NUM_SURFACES: usize = 12;
40
41fn get_rt_format(
43 profile: Profile,
44 bit_depth: BitDepth,
45 subsampling_x: bool,
46 subsampling_y: bool,
47) -> anyhow::Result<u32> {
48 match profile {
49 Profile::Profile0 => Ok(libva::constants::VA_RT_FORMAT_YUV420),
50 Profile::Profile1 => {
51 if subsampling_x && !subsampling_y {
52 Ok(libva::constants::VA_RT_FORMAT_YUV422)
53 } else if !subsampling_x && !subsampling_y {
54 Ok(libva::constants::VA_RT_FORMAT_YUV444)
55 } else {
56 Err(anyhow!(
57 "Unsupported subsampling for profile 1: X: {:?} Y: {:?}",
58 subsampling_x,
59 subsampling_y
60 ))
61 }
62 }
63 Profile::Profile2 => match bit_depth {
64 BitDepth::Depth8 => Err(anyhow!(
65 "Unsupported bit depth for profile 2: {:?}",
66 bit_depth
67 )),
68 BitDepth::Depth10 => Ok(libva::constants::VA_RT_FORMAT_YUV420_10),
69 BitDepth::Depth12 => Ok(libva::constants::VA_RT_FORMAT_YUV420_12),
70 },
71 Profile::Profile3 => {
72 if subsampling_x && !subsampling_y {
73 match bit_depth {
74 BitDepth::Depth8 => Err(anyhow!(
75 "Unsupported (subsampling_x, subsampling_y, bit depth) combination for profile 3: ({:?}, {:?}, {:?})",
76 subsampling_x,
77 subsampling_y,
78 bit_depth
79 )),
80 BitDepth::Depth10 => Ok(libva::constants::VA_RT_FORMAT_YUV422_10),
81 BitDepth::Depth12 => Ok(libva::constants::VA_RT_FORMAT_YUV422_12),
82 }
83 } else if !subsampling_x && !subsampling_y {
84 match bit_depth {
85 BitDepth::Depth8 => Err(anyhow!(
86 "Unsupported (subsampling_x, subsampling_y, bit depth) combination for profile 3: ({:?}, {:?}, {:?})",
87 subsampling_x,
88 subsampling_y,
89 bit_depth
90 )),
91 BitDepth::Depth10 => Ok(libva::constants::VA_RT_FORMAT_YUV444_10),
92 BitDepth::Depth12 => Ok(libva::constants::VA_RT_FORMAT_YUV444_12),
93 }
94 } else {
95 Err(anyhow!(
96 "Unsupported (subsampling_x, subsampling_y, bit depth) combination for profile 3: ({:?}, {:?}, {:?})",
97 subsampling_x,
98 subsampling_y,
99 bit_depth
100 ))
101 }
102 }
103 }
104}
105
106impl VaStreamInfo for &Header {
107 fn va_profile(&self) -> anyhow::Result<i32> {
108 Ok(match self.profile {
109 Profile::Profile0 => libva::VAProfile::VAProfileVP9Profile0,
110 Profile::Profile1 => libva::VAProfile::VAProfileVP9Profile1,
111 Profile::Profile2 => libva::VAProfile::VAProfileVP9Profile2,
112 Profile::Profile3 => libva::VAProfile::VAProfileVP9Profile3,
113 })
114 }
115
116 fn rt_format(&self) -> anyhow::Result<u32> {
117 get_rt_format(
118 self.profile,
119 self.bit_depth,
120 self.subsampling_x,
121 self.subsampling_y,
122 )
123 }
124
125 fn min_num_surfaces(&self) -> usize {
126 NUM_SURFACES
127 }
128
129 fn coded_size(&self) -> (u32, u32) {
130 (self.width, self.height)
131 }
132
133 fn visible_rect(&self) -> ((u32, u32), (u32, u32)) {
134 ((0, 0), self.coded_size())
135 }
136}
137
138fn build_pic_param(
139 hdr: &Header,
140 reference_frames: [u32; NUM_REF_FRAMES],
141) -> anyhow::Result<libva::BufferType> {
142 let pic_fields = libva::VP9PicFields::new(
143 hdr.subsampling_x as u32,
144 hdr.subsampling_y as u32,
145 hdr.frame_type as u32,
146 hdr.show_frame as u32,
147 hdr.error_resilient_mode as u32,
148 hdr.intra_only as u32,
149 hdr.allow_high_precision_mv as u32,
150 hdr.interpolation_filter as u32,
151 hdr.frame_parallel_decoding_mode as u32,
152 hdr.reset_frame_context as u32,
153 hdr.refresh_frame_context as u32,
154 hdr.frame_context_idx as u32,
155 hdr.seg.enabled as u32,
156 hdr.seg.temporal_update as u32,
157 hdr.seg.update_map as u32,
158 hdr.ref_frame_idx[LAST_FRAME - 1] as u32,
159 hdr.ref_frame_sign_bias[LAST_FRAME] as u32,
160 hdr.ref_frame_idx[GOLDEN_FRAME - 1] as u32,
161 hdr.ref_frame_sign_bias[GOLDEN_FRAME] as u32,
162 hdr.ref_frame_idx[ALTREF_FRAME - 1] as u32,
163 hdr.ref_frame_sign_bias[ALTREF_FRAME] as u32,
164 hdr.lossless as u32,
165 );
166
167 let lf = &hdr.lf;
168 let seg = &hdr.seg;
169
170 let seg_pred_prob = if seg.temporal_update {
171 seg.pred_probs
172 } else {
173 [0xff, 0xff, 0xff]
174 };
175
176 let pic_param = libva::PictureParameterBufferVP9::new(
177 hdr.width.try_into().unwrap(),
178 hdr.height.try_into().unwrap(),
179 reference_frames,
180 &pic_fields,
181 lf.level,
182 lf.sharpness,
183 hdr.tile_rows_log2,
184 hdr.tile_cols_log2,
185 hdr.uncompressed_header_size_in_bytes.try_into().unwrap(),
186 hdr.header_size_in_bytes,
187 seg.tree_probs,
188 seg_pred_prob,
189 hdr.profile as u8,
190 hdr.bit_depth as u8,
191 );
192
193 Ok(libva::BufferType::PictureParameter(
194 libva::PictureParameter::VP9(pic_param),
195 ))
196}
197
198fn build_slice_param(
199 seg: &[Segmentation; MAX_SEGMENTS],
200 slice_size: usize,
201) -> anyhow::Result<libva::BufferType> {
202 let seg_params: std::result::Result<[SegmentParameterVP9; MAX_SEGMENTS], _> = seg
203 .iter()
204 .map(|s| {
205 let seg_flags = libva::VP9SegmentFlags::new(
206 s.reference_frame_enabled as u16,
207 s.reference_frame as u16,
208 s.reference_skip_enabled as u16,
209 );
210
211 libva::SegmentParameterVP9::new(
212 &seg_flags,
213 s.lvl_lookup,
214 s.luma_ac_quant_scale,
215 s.luma_dc_quant_scale,
216 s.chroma_ac_quant_scale,
217 s.chroma_dc_quant_scale,
218 )
219 })
220 .collect::<Vec<_>>()
221 .try_into();
222
223 let seg_params = match seg_params {
224 Ok(seg_params) => seg_params,
225
226 Err(_) => panic!("Invalid segment parameters"),
229 };
230
231 Ok(libva::BufferType::SliceParameter(
232 libva::SliceParameter::VP9(libva::SliceParameterBufferVP9::new(
233 slice_size as u32,
234 0,
235 libva::constants::VA_SLICE_DATA_FLAG_ALL,
236 seg_params,
237 )),
238 ))
239}
240
241impl<M: SurfaceMemoryDescriptor + 'static> StatelessDecoderBackendPicture<Vp9> for VaapiBackend<M> {
242 type Picture = VaapiPicture<M>;
243}
244
245impl<M: SurfaceMemoryDescriptor + 'static> StatelessVp9DecoderBackend for VaapiBackend<M> {
246 fn new_sequence(&mut self, header: &Header) -> StatelessBackendResult<()> {
247 self.new_sequence(header, PoolCreationMode::Highest)
248 }
249
250 fn new_picture(&mut self, timestamp: u64) -> NewPictureResult<Self::Picture> {
251 let highest_pool = self.highest_pool();
252 let surface = highest_pool
253 .get_surface()
254 .ok_or(NewPictureError::OutOfOutputBuffers)?;
255 let metadata = self.metadata_state.get_parsed()?;
256 let context = &metadata.context;
257
258 Ok(VaPicture::new(timestamp, Rc::clone(context), surface))
259 }
260
261 fn submit_picture(
262 &mut self,
263 mut picture: Self::Picture,
264 hdr: &Header,
265 reference_frames: &[Option<Self::Handle>; NUM_REF_FRAMES],
266 bitstream: &[u8],
267 segmentation: &[Segmentation; MAX_SEGMENTS],
268 ) -> StatelessBackendResult<Self::Handle> {
269 let metadata = self.metadata_state.get_parsed()?;
270 let context = &metadata.context;
271
272 let reference_frames: [u32; NUM_REF_FRAMES] = reference_frames
273 .iter()
274 .map(va_surface_id)
275 .collect::<Vec<_>>()
276 .try_into()
277 .unwrap();
278
279 let pic_param = context
280 .create_buffer(build_pic_param(hdr, reference_frames)?)
281 .context("while creating pic params buffer")?;
282
283 let slice_param = context
284 .create_buffer(build_slice_param(segmentation, bitstream.len())?)
285 .context("while creating slice params buffer")?;
286
287 let slice_data = context
288 .create_buffer(libva::BufferType::SliceData(Vec::from(bitstream)))
289 .context("while creating slice data buffer")?;
290
291 picture.add_buffer(pic_param);
293 picture.add_buffer(slice_param);
294 picture.add_buffer(slice_data);
295
296 self.process_picture::<Vp9>(picture)
297 }
298}
299
300impl<M: SurfaceMemoryDescriptor + 'static> StatelessDecoder<Vp9, VaapiBackend<M>> {
301 pub fn new_vaapi<S>(
303 display: Rc<Display>,
304 blocking_mode: BlockingMode,
305 ) -> Result<Self, NewStatelessDecoderError>
306 where
307 M: From<S>,
308 S: From<M>,
309 {
310 Self::new(VaapiBackend::new(display, true), blocking_mode)
311 }
312}
313
314#[cfg(test)]
315mod tests {
316 use libva::BufferType;
317 use libva::Display;
318 use libva::PictureParameter;
319 use libva::SliceParameter;
320
321 use crate::codec::vp9::parser::Parser;
322 use crate::codec::vp9::parser::MAX_SEGMENTS;
323 use crate::codec::vp9::parser::NUM_REF_FRAMES;
324 use crate::decoder::stateless::tests::test_decode_stream;
325 use crate::decoder::stateless::tests::TestStream;
326 use crate::decoder::stateless::vp9::Segmentation;
327 use crate::decoder::BlockingMode;
328 use crate::utils::simple_playback_loop;
329 use crate::utils::simple_playback_loop_owned_frames;
330 use crate::utils::IvfIterator;
331 use crate::DecodedFormat;
332
333 use super::*;
334
335 fn test_decoder_vaapi(
337 test: &TestStream,
338 output_format: DecodedFormat,
339 blocking_mode: BlockingMode,
340 ) {
341 let display = Display::open().unwrap();
342 let decoder = StatelessDecoder::<Vp9, _>::new_vaapi::<()>(display, blocking_mode).unwrap();
343
344 test_decode_stream(
345 |d, s, c| {
346 simple_playback_loop(
347 d,
348 IvfIterator::new(s),
349 c,
350 &mut simple_playback_loop_owned_frames,
351 output_format,
352 blocking_mode,
353 )
354 },
355 decoder,
356 test,
357 true,
358 false,
359 );
360 }
361
362 #[test]
363 #[ignore]
365 fn test_25fps_block() {
366 use crate::decoder::stateless::vp9::tests::DECODE_TEST_25FPS;
367 test_decoder_vaapi(
368 &DECODE_TEST_25FPS,
369 DecodedFormat::NV12,
370 BlockingMode::Blocking,
371 );
372 }
373
374 #[test]
375 #[ignore]
377 fn test_25fps_nonblock() {
378 use crate::decoder::stateless::vp9::tests::DECODE_TEST_25FPS;
379 test_decoder_vaapi(
380 &DECODE_TEST_25FPS,
381 DecodedFormat::NV12,
382 BlockingMode::NonBlocking,
383 );
384 }
385
386 #[test]
387 #[ignore]
389 fn show_existing_frame_block() {
390 use crate::decoder::stateless::vp9::tests::DECODE_TEST_25FPS_SHOW_EXISTING_FRAME;
391 test_decoder_vaapi(
392 &DECODE_TEST_25FPS_SHOW_EXISTING_FRAME,
393 DecodedFormat::NV12,
394 BlockingMode::Blocking,
395 );
396 }
397
398 #[test]
399 #[ignore]
401 fn show_existing_frame_nonblock() {
402 use crate::decoder::stateless::vp9::tests::DECODE_TEST_25FPS_SHOW_EXISTING_FRAME;
403 test_decoder_vaapi(
404 &DECODE_TEST_25FPS_SHOW_EXISTING_FRAME,
405 DecodedFormat::NV12,
406 BlockingMode::NonBlocking,
407 );
408 }
409
410 #[test]
411 #[ignore]
413 fn show_existing_frame2_block() {
414 use crate::decoder::stateless::vp9::tests::DECODE_TEST_25FPS_SHOW_EXISTING_FRAME2;
415 test_decoder_vaapi(
416 &DECODE_TEST_25FPS_SHOW_EXISTING_FRAME2,
417 DecodedFormat::NV12,
418 BlockingMode::Blocking,
419 );
420 }
421
422 #[test]
423 #[ignore]
425 fn show_existing_frame2_nonblock() {
426 use crate::decoder::stateless::vp9::tests::DECODE_TEST_25FPS_SHOW_EXISTING_FRAME2;
427 test_decoder_vaapi(
428 &DECODE_TEST_25FPS_SHOW_EXISTING_FRAME2,
429 DecodedFormat::NV12,
430 BlockingMode::NonBlocking,
431 );
432 }
433
434 #[test]
435 #[ignore]
437 fn test_resolution_change_500frames_block() {
438 use crate::decoder::stateless::vp9::tests::DECODE_RESOLUTION_CHANGE_500FRAMES;
439 let display = Display::open().unwrap();
440 let decoder =
441 StatelessDecoder::<Vp9, _>::new_vaapi::<()>(display, BlockingMode::Blocking).unwrap();
442
443 test_decode_stream(
445 |d, s, c| {
446 simple_playback_loop(
447 d,
448 IvfIterator::new(s),
449 c,
450 &mut simple_playback_loop_owned_frames,
451 DecodedFormat::NV12,
452 BlockingMode::Blocking,
453 )
454 },
455 decoder,
456 &DECODE_RESOLUTION_CHANGE_500FRAMES,
457 false,
458 false,
459 );
460 }
461
462 #[test]
463 #[ignore]
465 fn test_resolution_change_500frames_nonblock() {
466 use crate::decoder::stateless::vp9::tests::DECODE_RESOLUTION_CHANGE_500FRAMES;
467 let display = Display::open().unwrap();
468 let decoder =
469 StatelessDecoder::<Vp9, _>::new_vaapi::<()>(display, BlockingMode::Blocking).unwrap();
470
471 test_decode_stream(
473 |d, s, c| {
474 simple_playback_loop(
475 d,
476 IvfIterator::new(s),
477 c,
478 &mut simple_playback_loop_owned_frames,
479 DecodedFormat::NV12,
480 BlockingMode::NonBlocking,
481 )
482 },
483 decoder,
484 &DECODE_RESOLUTION_CHANGE_500FRAMES,
485 false,
486 false,
487 );
488 }
489
490 #[test]
491 fn build_pic_params() {
493 const TEST_STREAM: &[u8] = include_bytes!("../../../codec/vp9/test_data/test-25fps.vp9");
494 let mut parser: Parser = Default::default();
495 let mut segmentation: [Segmentation; MAX_SEGMENTS] = Default::default();
496 let mut ivf_iter = IvfIterator::new(TEST_STREAM);
497
498 let packet = ivf_iter.next().unwrap();
501 let mut frames = parser.parse_chunk(packet).unwrap();
502 assert_eq!(frames.len(), 1);
503 let frame = frames.remove(0);
504
505 assert_eq!(frame.as_ref().len(), 10674);
506
507 let pic_param = build_pic_param(
508 &frame.header,
509 [libva::constants::VA_INVALID_SURFACE; NUM_REF_FRAMES],
510 )
511 .unwrap();
512 let pic_param = match pic_param {
513 BufferType::PictureParameter(PictureParameter::VP9(pic_param)) => pic_param,
514 _ => panic!(),
515 };
516
517 Segmentation::update_segmentation(&mut segmentation, &frame.header);
518 let slice_param = build_slice_param(&segmentation, frame.as_ref().len()).unwrap();
519 let slice_param = match slice_param {
520 BufferType::SliceParameter(SliceParameter::VP9(slice_param)) => slice_param,
521 _ => panic!(),
522 };
523
524 assert_eq!(pic_param.inner().frame_width, 320);
525 assert_eq!(pic_param.inner().frame_height, 240);
526 assert_eq!(
527 pic_param.inner().reference_frames,
528 [libva::constants::VA_INVALID_SURFACE; NUM_REF_FRAMES]
529 );
530
531 assert_eq!(unsafe { pic_param.inner().pic_fields.value }, unsafe {
533 libva::VP9PicFields::new(
534 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
535 )
536 .inner()
537 .value
538 });
539
540 assert_eq!(pic_param.inner().filter_level, 9);
541 assert_eq!(pic_param.inner().sharpness_level, 0);
542 assert_eq!(pic_param.inner().log2_tile_rows, 0);
543 assert_eq!(pic_param.inner().log2_tile_columns, 0);
544 assert_eq!(pic_param.inner().frame_header_length_in_bytes, 18);
545 assert_eq!(pic_param.inner().first_partition_size, 120);
546 assert_eq!(pic_param.inner().mb_segment_tree_probs, [0; 7]);
547 assert_eq!(pic_param.inner().segment_pred_probs, [0xff; 3]);
548 assert_eq!(pic_param.inner().profile, 0);
549 assert_eq!(pic_param.inner().bit_depth, 8);
550
551 assert_eq!(slice_param.inner().slice_data_size, 10674);
552 assert_eq!(slice_param.inner().slice_data_offset, 0);
553 assert_eq!(
554 slice_param.inner().slice_data_flag,
555 libva::constants::VA_SLICE_DATA_FLAG_ALL
556 );
557
558 for seg_param in &slice_param.inner().seg_param {
559 assert_eq!(unsafe { seg_param.segment_flags.value }, 0);
561 assert_eq!(seg_param.filter_level, [[10, 0], [9, 9], [8, 8], [8, 8]]);
562 assert_eq!(seg_param.luma_ac_quant_scale, 72);
563 assert_eq!(seg_param.luma_dc_quant_scale, 62);
564 assert_eq!(seg_param.chroma_ac_quant_scale, 72);
565 assert_eq!(seg_param.chroma_dc_quant_scale, 62);
566 }
567
568 let packet = ivf_iter.next().unwrap();
571 let mut frames = parser.parse_chunk(packet).unwrap();
572 assert_eq!(frames.len(), 2);
573 let frame = frames.remove(0);
574 assert_eq!(frame.as_ref().len(), 2390);
575
576 let pic_param = build_pic_param(&frame.header, [0; NUM_REF_FRAMES]).unwrap();
577 let pic_param = match pic_param {
578 BufferType::PictureParameter(PictureParameter::VP9(pic_param)) => pic_param,
579 _ => panic!(),
580 };
581
582 Segmentation::update_segmentation(&mut segmentation, &frame.header);
583 let slice_param = build_slice_param(&segmentation, frame.as_ref().len()).unwrap();
584 let slice_param = match slice_param {
585 BufferType::SliceParameter(SliceParameter::VP9(slice_param)) => slice_param,
586 _ => panic!(),
587 };
588
589 assert_eq!(pic_param.inner().frame_width, 320);
590 assert_eq!(pic_param.inner().frame_height, 240);
591 assert_eq!(pic_param.inner().reference_frames, [0; NUM_REF_FRAMES]);
592 assert_eq!(unsafe { pic_param.inner().pic_fields.value }, unsafe {
594 libva::VP9PicFields::new(
595 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0,
596 )
597 .inner()
598 .value
599 });
600
601 assert_eq!(pic_param.inner().filter_level, 15);
602 assert_eq!(pic_param.inner().sharpness_level, 0);
603 assert_eq!(pic_param.inner().log2_tile_rows, 0);
604 assert_eq!(pic_param.inner().log2_tile_columns, 0);
605 assert_eq!(pic_param.inner().frame_header_length_in_bytes, 11);
606 assert_eq!(pic_param.inner().first_partition_size, 48);
607 assert_eq!(pic_param.inner().mb_segment_tree_probs, [0; 7]);
608 assert_eq!(pic_param.inner().segment_pred_probs, [0xff; 3]);
609 assert_eq!(pic_param.inner().profile, 0);
610 assert_eq!(pic_param.inner().bit_depth, 8);
611
612 assert_eq!(slice_param.inner().slice_data_size, 2390);
613 assert_eq!(slice_param.inner().slice_data_offset, 0);
614 assert_eq!(
615 slice_param.inner().slice_data_flag,
616 libva::constants::VA_SLICE_DATA_FLAG_ALL
617 );
618
619 for seg_param in &slice_param.inner().seg_param {
620 assert_eq!(unsafe { seg_param.segment_flags.value }, 0);
622 assert_eq!(
623 seg_param.filter_level,
624 [[16, 0], [15, 15], [14, 14], [14, 14]]
625 );
626 assert_eq!(seg_param.luma_ac_quant_scale, 136);
627 assert_eq!(seg_param.luma_dc_quant_scale, 111);
628 assert_eq!(seg_param.chroma_ac_quant_scale, 136);
629 assert_eq!(seg_param.chroma_dc_quant_scale, 111);
630 }
631
632 let frame = frames.remove(0);
635 assert_eq!(frame.as_ref().len(), 108);
636
637 let pic_param = build_pic_param(&frame.header, [0, 0, 1, 0, 0, 0, 0, 0]).unwrap();
638 let pic_param = match pic_param {
639 BufferType::PictureParameter(PictureParameter::VP9(pic_param)) => pic_param,
640 _ => panic!(),
641 };
642
643 Segmentation::update_segmentation(&mut segmentation, &frame.header);
644 let slice_param = build_slice_param(&segmentation, frame.as_ref().len()).unwrap();
645 let slice_param = match slice_param {
646 BufferType::SliceParameter(SliceParameter::VP9(slice_param)) => slice_param,
647 _ => panic!(),
648 };
649
650 assert_eq!(pic_param.inner().frame_width, 320);
651 assert_eq!(pic_param.inner().frame_height, 240);
652 assert_eq!(pic_param.inner().reference_frames, [0, 0, 1, 0, 0, 0, 0, 0]);
653
654 assert_eq!(unsafe { pic_param.inner().pic_fields.value }, unsafe {
656 libva::VP9PicFields::new(
657 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 2, 1, 0,
658 )
659 .inner()
660 .value
661 });
662
663 assert_eq!(pic_param.inner().filter_level, 36);
664 assert_eq!(pic_param.inner().sharpness_level, 0);
665 assert_eq!(pic_param.inner().log2_tile_rows, 0);
666 assert_eq!(pic_param.inner().log2_tile_columns, 0);
667 assert_eq!(pic_param.inner().frame_header_length_in_bytes, 10);
668 assert_eq!(pic_param.inner().first_partition_size, 9);
669 assert_eq!(pic_param.inner().mb_segment_tree_probs, [0; 7]);
670 assert_eq!(pic_param.inner().segment_pred_probs, [0xff; 3]);
671 assert_eq!(pic_param.inner().profile, 0);
672 assert_eq!(pic_param.inner().bit_depth, 8);
673
674 assert_eq!(slice_param.inner().slice_data_size, 108);
675 assert_eq!(slice_param.inner().slice_data_offset, 0);
676 assert_eq!(
677 slice_param.inner().slice_data_flag,
678 libva::constants::VA_SLICE_DATA_FLAG_ALL
679 );
680
681 for seg_param in &slice_param.inner().seg_param {
682 assert_eq!(unsafe { seg_param.segment_flags.value }, 0);
684 assert_eq!(
685 seg_param.filter_level,
686 [[38, 0], [36, 36], [34, 34], [34, 34]]
687 );
688 assert_eq!(seg_param.luma_ac_quant_scale, 864);
689 assert_eq!(seg_param.luma_dc_quant_scale, 489);
690 assert_eq!(seg_param.chroma_ac_quant_scale, 864);
691 assert_eq!(seg_param.chroma_dc_quant_scale, 489);
692 }
693 }
694}