@@ -174,47 +174,149 @@ fn supported_formats_for_rt_format(
174
174
Ok ( supported_formats)
175
175
}
176
176
177
- /// A decoded frame handle.
178
- pub ( crate ) type DecodedHandle < M > = Rc < RefCell < GenericBackendHandle < M > > > ;
177
+ pub ( crate ) type DecodedHandle < M > = Rc < RefCell < VaDecodedHandle < M > > > ;
179
178
180
- impl < M : SurfaceMemoryDescriptor > DecodedHandleTrait for DecodedHandle < M > {
179
+ /// The handle type used by the decoder backend that takes into account whether
180
+ /// post processing is needed.
181
+ pub enum VaDecodedHandle < M : SurfaceMemoryDescriptor > {
182
+ Generic ( GenericBackendHandle < M > ) ,
183
+ PostProcessed ( PostProcessedHandle < M > ) ,
184
+ }
185
+
186
+ impl < M : SurfaceMemoryDescriptor > VaDecodedHandle < M > {
187
+ fn handle ( & self ) -> & GenericBackendHandle < M > {
188
+ match self {
189
+ VaDecodedHandle :: Generic ( h) => h,
190
+ VaDecodedHandle :: PostProcessed ( h) => & h. decode_handle ,
191
+ }
192
+ }
193
+
194
+ fn handle_mut ( & mut self ) -> & mut GenericBackendHandle < M > {
195
+ match self {
196
+ VaDecodedHandle :: Generic ( h) => h,
197
+ VaDecodedHandle :: PostProcessed ( h) => & mut h. decode_handle ,
198
+ }
199
+ }
200
+
201
+ pub ( crate ) fn decoded_surface_id ( & self ) -> libva:: VASurfaceID {
202
+ match & self . handle ( ) . state {
203
+ PictureState :: Ready ( picture) => picture. surface ( ) . id ( ) ,
204
+ PictureState :: Pending ( picture) => picture. surface ( ) . id ( ) ,
205
+ PictureState :: Invalid => unreachable ! ( ) ,
206
+ }
207
+ }
208
+
209
+ /// Returns the picture of this handle.
210
+ pub ( crate ) fn picture ( & self ) -> Option < & Picture < PictureSync , PooledSurface < M > > > {
211
+ match self {
212
+ VaDecodedHandle :: Generic ( h) => h. picture ( ) ,
213
+ VaDecodedHandle :: PostProcessed ( h) => h. picture ( ) ,
214
+ }
215
+ }
216
+ }
217
+
218
+ impl < M : SurfaceMemoryDescriptor > DecodedHandleTrait for Rc < RefCell < VaDecodedHandle < M > > > {
181
219
type Descriptor = M ;
182
220
183
221
fn coded_resolution ( & self ) -> Resolution {
184
- self . borrow ( ) . coded_resolution
222
+ self . borrow ( ) . handle ( ) . coded_resolution
185
223
}
186
224
187
225
fn display_resolution ( & self ) -> Resolution {
188
- self . borrow ( ) . display_resolution
226
+ self . borrow ( ) . handle ( ) . display_resolution
189
227
}
190
228
191
229
fn timestamp ( & self ) -> u64 {
192
- self . borrow ( ) . timestamp ( )
230
+ self . borrow ( ) . handle ( ) . timestamp ( )
193
231
}
194
232
195
233
fn dyn_picture < ' a > ( & ' a self ) -> Box < dyn DynHandle + ' a > {
196
234
Box :: new ( self . borrow ( ) )
197
235
}
198
236
199
237
fn is_ready ( & self ) -> bool {
200
- self . borrow ( ) . is_va_ready ( ) . unwrap_or ( true )
238
+ let borrow = self . borrow ( ) ;
239
+ let handle = borrow. handle ( ) ;
240
+
241
+ let decode_is_ready = match & handle. state {
242
+ PictureState :: Ready ( _) => Ok ( true ) ,
243
+ PictureState :: Pending ( picture) => picture
244
+ . surface ( )
245
+ . query_status ( )
246
+ . map ( |s| s == libva:: VASurfaceStatus :: VASurfaceReady ) ,
247
+ PictureState :: Invalid => unreachable ! ( ) ,
248
+ }
249
+ . unwrap_or ( true ) ;
250
+
251
+ match & * self . borrow ( ) {
252
+ VaDecodedHandle :: Generic ( _) => decode_is_ready,
253
+ VaDecodedHandle :: PostProcessed ( h) => {
254
+ use std:: borrow:: Borrow ;
255
+ let display_surface: & libva:: Surface < M > = h. display_surface . borrow ( ) ;
256
+
257
+ let display_is_ready = display_surface
258
+ . query_status ( )
259
+ . map ( |s| s == libva:: VASurfaceStatus :: VASurfaceReady )
260
+ . unwrap_or ( true ) ;
261
+
262
+ decode_is_ready && display_is_ready
263
+ }
264
+ }
201
265
}
202
266
203
267
fn sync ( & self ) -> anyhow:: Result < ( ) > {
204
- self . borrow_mut ( ) . sync ( ) . context ( "while syncing picture" ) ?;
205
-
206
- Ok ( ( ) )
268
+ let mut borrow = self . borrow_mut ( ) ;
269
+ let handle = borrow. handle_mut ( ) ;
270
+ handle. sync ( ) . context ( "while syncing picture" ) ?;
271
+
272
+ match & * borrow {
273
+ VaDecodedHandle :: Generic ( _) => Ok ( ( ) ) ,
274
+ VaDecodedHandle :: PostProcessed ( h) => {
275
+ use std:: borrow:: Borrow ;
276
+ let display_surface: & libva:: Surface < M > = h. display_surface . borrow ( ) ;
277
+ display_surface
278
+ . sync ( )
279
+ . context ( "while syncing the display surface" )
280
+ }
281
+ }
207
282
}
208
283
209
284
fn resource ( & self ) -> std:: cell:: Ref < M > {
210
- std:: cell:: Ref :: map ( self . borrow ( ) , |r| match & r. state {
211
- PictureState :: Ready ( p) => p. surface ( ) . as_ref ( ) ,
212
- PictureState :: Pending ( p) => p. surface ( ) . as_ref ( ) ,
213
- PictureState :: Invalid => unreachable ! ( ) ,
285
+ std:: cell:: Ref :: map ( self . borrow ( ) , |r| match r {
286
+ VaDecodedHandle :: Generic ( h) => match & h. state {
287
+ PictureState :: Ready ( p) => p. surface ( ) . as_ref ( ) ,
288
+ PictureState :: Pending ( p) => p. surface ( ) . as_ref ( ) ,
289
+ PictureState :: Invalid => unreachable ! ( ) ,
290
+ } ,
291
+ VaDecodedHandle :: PostProcessed ( h) => {
292
+ /* return the display resource, as this is what most clients care about */
293
+ h. display_surface . as_ref ( )
294
+ }
214
295
} )
215
296
}
216
297
}
217
298
299
+ impl < ' a , M : SurfaceMemoryDescriptor > DynHandle for std:: cell:: Ref < ' a , VaDecodedHandle < M > > {
300
+ fn dyn_mappable_handle < ' b > ( & ' b self ) -> anyhow:: Result < Box < dyn MappableHandle + ' b > > {
301
+ match & * * self {
302
+ VaDecodedHandle :: Generic ( h) => {
303
+ h. image ( ) . map ( |i| Box :: new ( i) as Box < dyn MappableHandle > )
304
+ }
305
+ VaDecodedHandle :: PostProcessed ( h) => {
306
+ use std:: borrow:: Borrow ;
307
+ let surface: & libva:: Surface < M > = h. display_surface . borrow ( ) ;
308
+ let image = libva:: Image :: create_from (
309
+ surface,
310
+ * h. decode_handle . map_format ,
311
+ h. decode_handle . coded_resolution . into ( ) ,
312
+ h. decode_handle . display_resolution . into ( ) ,
313
+ ) ?;
314
+ Ok ( Box :: new ( image) as Box < dyn MappableHandle > )
315
+ }
316
+ }
317
+ }
318
+ }
319
+
218
320
mod surface_pool {
219
321
use std:: borrow:: Borrow ;
220
322
use std:: cell:: RefCell ;
@@ -691,6 +793,35 @@ impl StreamMetadataState {
691
793
}
692
794
}
693
795
796
+ /// A handle that can be post processed. One surface holds the non-filtered data
797
+ /// and is fed to the decode process, the other holds the filtered data and is
798
+ /// meant to be displayed.
799
+ pub struct PostProcessedHandle < M : SurfaceMemoryDescriptor > {
800
+ /// The non-filtered handle. All decoding happens here.
801
+ decode_handle : GenericBackendHandle < M > ,
802
+ /// The filtered surface. We merely display it.
803
+ display_surface : PooledSurface < M > ,
804
+ }
805
+
806
+ impl < M : SurfaceMemoryDescriptor > PostProcessedHandle < M > {
807
+ /// Creates a new pending handle on `surface_id`.
808
+ fn new (
809
+ picture : Picture < PictureNew , PooledSurface < M > > ,
810
+ metadata : & ParsedStreamMetadata ,
811
+ display_surface : PooledSurface < M > ,
812
+ ) -> anyhow:: Result < Self > {
813
+ Ok ( Self {
814
+ decode_handle : GenericBackendHandle :: new ( picture, metadata) ?,
815
+ display_surface,
816
+ } )
817
+ }
818
+
819
+ /// Returns the picture of this handle.
820
+ pub ( crate ) fn picture ( & self ) -> Option < & Picture < PictureSync , PooledSurface < M > > > {
821
+ self . decode_handle . picture ( )
822
+ }
823
+ }
824
+
694
825
/// VA-API backend handle.
695
826
///
696
827
/// This includes the VA picture which can be pending rendering or complete, as well as useful
@@ -777,32 +908,6 @@ impl<M: SurfaceMemoryDescriptor> GenericBackendHandle<M> {
777
908
PictureState :: Invalid => unreachable ! ( ) ,
778
909
}
779
910
}
780
-
781
- /// Returns the id of the VA surface backing this handle.
782
- pub ( crate ) fn surface_id ( & self ) -> libva:: VASurfaceID {
783
- match & self . state {
784
- PictureState :: Ready ( picture) => picture. surface ( ) . id ( ) ,
785
- PictureState :: Pending ( picture) => picture. surface ( ) . id ( ) ,
786
- PictureState :: Invalid => unreachable ! ( ) ,
787
- }
788
- }
789
-
790
- fn is_va_ready ( & self ) -> Result < bool , VaError > {
791
- match & self . state {
792
- PictureState :: Ready ( _) => Ok ( true ) ,
793
- PictureState :: Pending ( picture) => picture
794
- . surface ( )
795
- . query_status ( )
796
- . map ( |s| s == libva:: VASurfaceStatus :: VASurfaceReady ) ,
797
- PictureState :: Invalid => unreachable ! ( ) ,
798
- }
799
- }
800
- }
801
-
802
- impl < ' a , M : SurfaceMemoryDescriptor > DynHandle for std:: cell:: Ref < ' a , GenericBackendHandle < M > > {
803
- fn dyn_mappable_handle < ' b > ( & ' b self ) -> anyhow:: Result < Box < dyn MappableHandle + ' b > > {
804
- self . image ( ) . map ( |i| Box :: new ( i) as Box < dyn MappableHandle > )
805
- }
806
911
}
807
912
808
913
/// Rendering state of a VA picture.
@@ -1000,9 +1105,27 @@ where
1000
1105
{
1001
1106
let metadata = self . metadata_state . get_parsed ( ) ?;
1002
1107
1003
- Ok ( Rc :: new ( RefCell :: new ( GenericBackendHandle :: new (
1004
- picture, metadata,
1005
- ) ?) ) )
1108
+ let handle = GenericBackendHandle :: new ( picture, metadata) ?;
1109
+ let handle = Rc :: new ( RefCell :: new ( VaDecodedHandle :: Generic ( handle) ) ) ;
1110
+ Ok ( handle)
1111
+ }
1112
+
1113
+ /// Process an AV1 picture. AV1 supports film grain, and its use requires a
1114
+ /// different type of Handle.
1115
+ pub ( crate ) fn process_av1_picture < Codec : StatelessCodec > (
1116
+ & mut self ,
1117
+ picture : Picture < PictureNew , PooledSurface < M > > ,
1118
+ display_surface : PooledSurface < M > ,
1119
+ ) -> StatelessBackendResult < <Self as StatelessDecoderBackend < Codec > >:: Handle >
1120
+ where
1121
+ Self : StatelessDecoderBackendPicture < Codec > ,
1122
+ for < ' a > & ' a Codec :: FormatInfo : VaStreamInfo ,
1123
+ {
1124
+ let metadata = self . metadata_state . get_parsed ( ) ?;
1125
+
1126
+ let handle = PostProcessedHandle :: new ( picture, metadata, display_surface) ?;
1127
+ let handle = Rc :: new ( RefCell :: new ( VaDecodedHandle :: PostProcessed ( handle) ) ) ;
1128
+ Ok ( handle)
1006
1129
}
1007
1130
1008
1131
/// Gets a set of supported formats for the particular stream being
0 commit comments