@@ -12,6 +12,7 @@ use libva::SurfaceMemoryDescriptor;
12
12
13
13
use crate :: backend:: vaapi:: DecodedHandle as VADecodedHandle ;
14
14
use crate :: backend:: vaapi:: PoolCreationMode ;
15
+ use crate :: backend:: vaapi:: PooledSurface ;
15
16
use crate :: backend:: vaapi:: VaStreamInfo ;
16
17
use crate :: backend:: vaapi:: VaapiBackend ;
17
18
use crate :: backend:: vaapi:: VaapiPicture ;
@@ -87,7 +88,13 @@ impl VaStreamInfo for &Rc<SequenceHeaderObu> {
87
88
}
88
89
89
90
fn min_num_surfaces ( & self ) -> usize {
90
- NUM_SURFACES
91
+ if self . film_grain_params_present {
92
+ /* assume grain will be applied. We need twice the number of surfaces
93
+ * for that. */
94
+ NUM_SURFACES * 2
95
+ } else {
96
+ NUM_SURFACES
97
+ }
91
98
}
92
99
93
100
fn coded_size ( & self ) -> ( u32 , u32 ) {
@@ -271,6 +278,7 @@ fn build_pic_param<M: SurfaceMemoryDescriptor>(
271
278
hdr : & FrameHeaderObu ,
272
279
seq : & SequenceHeaderObu ,
273
280
current_frame : libva:: VASurfaceID ,
281
+ current_display_picture : libva:: VASurfaceID ,
274
282
reference_frames : & [ Option < VADecodedHandle < M > > ; NUM_REF_FRAMES ] ,
275
283
) -> anyhow:: Result < libva:: BufferType > {
276
284
let seq_info_fields = libva:: AV1SeqFields :: new (
@@ -487,8 +495,8 @@ fn build_pic_param<M: SurfaceMemoryDescriptor>(
487
495
. context ( "Invalid matrix_coefficients" ) ?,
488
496
& seq_info_fields,
489
497
current_frame,
490
- libva :: constants :: VA_INVALID_SURFACE , /* film grain is unsupported for now */
491
- vec ! [ ] , /* anchor_frames_list */
498
+ current_display_picture ,
499
+ vec ! [ ] , /* anchor_frames_list */
492
500
u16:: try_from ( hdr. upscaled_width - 1 ) . context ( "Invalid frame width" ) ?,
493
501
u16:: try_from ( hdr. frame_height - 1 ) . context ( "Invalid frame height" ) ?,
494
502
0 , /* output_frame_width_in_tiles_minus_1 */
@@ -564,8 +572,14 @@ fn build_slice_data_for_tg(tg: TileGroupObu) -> libva::BufferType {
564
572
libva:: BufferType :: SliceData ( Vec :: from ( obu. as_ref ( ) ) )
565
573
}
566
574
575
+ pub struct Picture < M : SurfaceMemoryDescriptor + ' static > {
576
+ va_picture : VaapiPicture < M > ,
577
+ /// Some if film grain is to be applied.
578
+ display_surface : Option < PooledSurface < M > > ,
579
+ }
580
+
567
581
impl < M : SurfaceMemoryDescriptor + ' static > StatelessDecoderBackendPicture < Av1 > for VaapiBackend < M > {
568
- type Picture = VaapiPicture < M > ;
582
+ type Picture = Picture < M > ;
569
583
}
570
584
571
585
impl < M : SurfaceMemoryDescriptor + ' static > StatelessAV1DecoderBackend for VaapiBackend < M > {
@@ -598,7 +612,7 @@ impl<M: SurfaceMemoryDescriptor + 'static> StatelessAV1DecoderBackend for VaapiB
598
612
reference_frames : & [ Option < Self :: Handle > ; NUM_REF_FRAMES ] ,
599
613
highest_spatial_layer : Option < u32 > ,
600
614
) -> crate :: decoder:: stateless:: StatelessBackendResult < Self :: Picture > {
601
- let surface = match highest_spatial_layer {
615
+ let ( decode_surface , display_surface ) = match highest_spatial_layer {
602
616
Some ( _) => {
603
617
let layer = Resolution {
604
618
width : hdr. upscaled_width ,
@@ -611,33 +625,77 @@ impl<M: SurfaceMemoryDescriptor + 'static> StatelessAV1DecoderBackend for VaapiB
611
625
"No pool available for this layer"
612
626
) ) ) ?;
613
627
614
- pool. borrow_mut ( )
628
+ let decode_surface = pool
629
+ . borrow_mut ( )
615
630
. get_surface ( pool)
616
- . ok_or ( StatelessBackendError :: OutOfResources ) ?
631
+ . ok_or ( StatelessBackendError :: OutOfResources ) ?;
632
+
633
+ let display_surface = if hdr. film_grain_params . apply_grain {
634
+ Some (
635
+ pool. borrow_mut ( )
636
+ . get_surface ( pool)
637
+ . ok_or ( StatelessBackendError :: OutOfResources ) ?,
638
+ )
639
+ } else {
640
+ None
641
+ } ;
642
+
643
+ ( decode_surface, display_surface)
617
644
}
618
645
None => {
619
646
let highest_pool = self . highest_pool ( ) ;
620
- highest_pool
647
+
648
+ let decode_surface = highest_pool
621
649
. borrow_mut ( )
622
650
. get_surface ( highest_pool)
623
- . ok_or ( StatelessBackendError :: OutOfResources ) ?
651
+ . ok_or ( StatelessBackendError :: OutOfResources ) ?;
652
+
653
+ let display_surface = if hdr. film_grain_params . apply_grain {
654
+ Some (
655
+ highest_pool
656
+ . borrow_mut ( )
657
+ . get_surface ( highest_pool)
658
+ . ok_or ( StatelessBackendError :: OutOfResources ) ?,
659
+ )
660
+ } else {
661
+ None
662
+ } ;
663
+
664
+ ( decode_surface, display_surface)
624
665
}
625
666
} ;
626
667
627
668
let metadata = self . metadata_state . get_parsed ( ) ?;
628
- let mut picture = VaPicture :: new ( timestamp, Rc :: clone ( & metadata. context ) , surface ) ;
669
+ let mut picture = VaPicture :: new ( timestamp, Rc :: clone ( & metadata. context ) , decode_surface ) ;
629
670
630
671
let surface_id = picture. surface ( ) . id ( ) ;
672
+ let display_surface_id = match display_surface {
673
+ Some ( ref pooled_surface) => {
674
+ use std:: borrow:: Borrow ;
675
+ let display_surface: & libva:: Surface < M > = pooled_surface. borrow ( ) ;
676
+ display_surface. id ( )
677
+ }
678
+ None => libva:: constants:: VA_INVALID_SURFACE ,
679
+ } ;
631
680
632
- let pic_param = build_pic_param ( hdr, sequence, surface_id, reference_frames)
633
- . context ( "Failed to build picture parameter" ) ?;
681
+ let pic_param = build_pic_param (
682
+ hdr,
683
+ sequence,
684
+ surface_id,
685
+ display_surface_id,
686
+ reference_frames,
687
+ )
688
+ . context ( "Failed to build picture parameter" ) ?;
634
689
let pic_param = metadata
635
690
. context
636
691
. create_buffer ( pic_param)
637
692
. context ( "Failed to create picture parameter buffer" ) ?;
638
693
picture. add_buffer ( pic_param) ;
639
694
640
- Ok ( picture)
695
+ Ok ( Picture {
696
+ va_picture : picture,
697
+ display_surface,
698
+ } )
641
699
}
642
700
643
701
fn decode_tile_group (
@@ -655,13 +713,13 @@ impl<M: SurfaceMemoryDescriptor + 'static> StatelessAV1DecoderBackend for VaapiB
655
713
. create_buffer ( slice_params)
656
714
. context ( "Failed to create slice parameter buffer" ) ?;
657
715
658
- picture. add_buffer ( buffer) ;
716
+ picture. va_picture . add_buffer ( buffer) ;
659
717
660
718
let buffer = context
661
719
. create_buffer ( slice_data)
662
720
. context ( "Failed to create slice data buffer" ) ?;
663
721
664
- picture. add_buffer ( buffer) ;
722
+ picture. va_picture . add_buffer ( buffer) ;
665
723
666
724
Ok ( ( ) )
667
725
}
@@ -670,7 +728,16 @@ impl<M: SurfaceMemoryDescriptor + 'static> StatelessAV1DecoderBackend for VaapiB
670
728
& mut self ,
671
729
picture : Self :: Picture ,
672
730
) -> crate :: decoder:: stateless:: StatelessBackendResult < Self :: Handle > {
673
- self . process_picture :: < Av1 > ( picture)
731
+ let Picture {
732
+ va_picture,
733
+ display_surface,
734
+ } = picture;
735
+
736
+ if let Some ( display_surface) = display_surface {
737
+ self . process_av1_picture :: < Av1 > ( va_picture, display_surface)
738
+ } else {
739
+ self . process_picture :: < Av1 > ( va_picture)
740
+ }
674
741
}
675
742
}
676
743
0 commit comments