55use std:: any:: Any ;
66use std:: marker:: PhantomData ;
77use std:: rc:: Rc ;
8+ use std:: sync:: Arc ;
89
910use anyhow:: anyhow;
1011use libva:: Config ;
@@ -17,6 +18,7 @@ use libva::PictureEnd;
1718use libva:: Surface ;
1819use libva:: SurfaceMemoryDescriptor ;
1920use libva:: UsageHint ;
21+ use libva:: VAEntrypoint ;
2022use libva:: VAEntrypoint :: VAEntrypointEncSlice ;
2123use libva:: VAEntrypoint :: VAEntrypointEncSliceLP ;
2224use libva:: VAProfile ;
@@ -52,11 +54,14 @@ impl From<libva::VaError> for StatelessBackendError {
5254pub ( crate ) fn tunings_to_libva_rc < const CLAMP_MIN_QP : u32 , const CLAMP_MAX_QP : u32 > (
5355 tunings : & Tunings ,
5456) -> StatelessBackendResult < libva:: EncMiscParameterRateControl > {
55- let bits_per_second = tunings. rate_control . bitrate_target ( ) . unwrap_or ( 0 ) ;
57+ let bits_per_second = tunings. rate_control . bitrate_maximum ( ) . unwrap_or ( 0 ) ;
58+ let target_bits_per_second = tunings. rate_control . bitrate_target ( ) . unwrap_or ( bits_per_second) ;
59+
5660 let bits_per_second = u32:: try_from ( bits_per_second) . map_err ( |e| anyhow:: anyhow!( e) ) ?;
61+ let target_bits_per_second =
62+ u32:: try_from ( target_bits_per_second) . map_err ( |e| anyhow:: anyhow!( e) ) ?;
5763
58- // At the moment we don't support variable bitrate therefore target 100%
59- const TARGET_PERCENTAGE : u32 = 100 ;
64+ let target_percentage: u32 = 100 * target_bits_per_second / bits_per_second;
6065
6166 // Window size in ms that the RC should apply to
6267 const WINDOW_SIZE : u32 = 1_500 ;
@@ -70,10 +75,10 @@ pub(crate) fn tunings_to_libva_rc<const CLAMP_MIN_QP: u32, const CLAMP_MAX_QP: u
7075 const RESET : u32 = 0 ;
7176
7277 // Don't skip frames
73- const DISABLE_FRAME_SKIP : u32 = 1 ;
78+ const DISABLE_FRAME_SKIP : u32 = 0 ;
7479
7580 // Allow bit stuffing
76- const DISABLE_BIT_STUFFING : u32 = 0 ;
81+ const DISABLE_BIT_STUFFING : u32 = 1 ;
7782
7883 // Use default
7984 const MB_RATE_CONTROL : u32 = 0 ;
@@ -113,7 +118,7 @@ pub(crate) fn tunings_to_libva_rc<const CLAMP_MIN_QP: u32, const CLAMP_MAX_QP: u
113118
114119 Ok ( libva:: EncMiscParameterRateControl :: new (
115120 bits_per_second,
116- TARGET_PERCENTAGE ,
121+ target_percentage ,
117122 WINDOW_SIZE ,
118123 initial_qp,
119124 min_qp,
@@ -161,7 +166,8 @@ where
161166 /// VA context used for encoding.
162167 context : Rc < Context > ,
163168
164- _va_profile : VAProfile :: Type ,
169+ va_profile : VAProfile :: Type ,
170+ entrypoint : VAEntrypoint :: Type ,
165171 scratch_pool : VaSurfacePool < ( ) > ,
166172 _phantom : PhantomData < ( M , H ) > ,
167173}
@@ -172,7 +178,7 @@ where
172178 H : std:: borrow:: Borrow < Surface < M > > ,
173179{
174180 pub fn new (
175- display : Rc < Display > ,
181+ display : Arc < Display > ,
176182 va_profile : VAProfile :: Type ,
177183 fourcc : Fourcc ,
178184 coded_size : Resolution ,
@@ -185,6 +191,7 @@ where
185191 . ok_or_else ( || StatelessBackendError :: UnsupportedFormat ) ?;
186192
187193 let rt_format = format_map. rt_format ;
194+ let entrypoint = if low_power { VAEntrypointEncSliceLP } else { VAEntrypointEncSlice } ;
188195
189196 let va_config = display. create_config (
190197 vec ! [
@@ -198,7 +205,7 @@ where
198205 } ,
199206 ] ,
200207 va_profile,
201- if low_power { VAEntrypointEncSliceLP } else { VAEntrypointEncSlice } ,
208+ entrypoint ,
202209 ) ?;
203210
204211 let context = display. create_context :: < M > (
@@ -210,7 +217,7 @@ where
210217 ) ?;
211218
212219 let mut scratch_pool = VaSurfacePool :: new (
213- Rc :: clone ( & display) ,
220+ Arc :: clone ( & display) ,
214221 rt_format,
215222 Some ( UsageHint :: USAGE_HINT_ENCODER ) ,
216223 coded_size,
@@ -223,7 +230,8 @@ where
223230 va_config,
224231 context,
225232 scratch_pool,
226- _va_profile : va_profile,
233+ va_profile,
234+ entrypoint,
227235 _phantom : Default :: default ( ) ,
228236 } )
229237 }
@@ -271,6 +279,51 @@ where
271279
272280 Ok ( Reconstructed ( surface) )
273281 }
282+
283+ pub ( crate ) fn supports_max_frame_size ( & self ) -> StatelessBackendResult < bool > {
284+ let display = self . context ( ) . display ( ) ;
285+ let mut attrs = [ libva:: VAConfigAttrib {
286+ type_ : libva:: VAConfigAttribType :: VAConfigAttribMaxFrameSize ,
287+ value : 0 ,
288+ } ] ;
289+
290+ display. get_config_attributes ( self . va_profile , self . entrypoint , & mut attrs) ?;
291+
292+ if attrs[ 0 ] . value == libva:: VA_ATTRIB_NOT_SUPPORTED {
293+ return Ok ( false ) ;
294+ }
295+ Ok ( true )
296+ }
297+
298+ pub ( crate ) fn supports_quality_range ( & self , quality : u32 ) -> StatelessBackendResult < bool > {
299+ let display = self . context ( ) . display ( ) ;
300+ let mut attrs = [ libva:: VAConfigAttrib {
301+ type_ : libva:: VAConfigAttribType :: VAConfigAttribEncQualityRange ,
302+ value : 0 ,
303+ } ] ;
304+
305+ display. get_config_attributes ( self . va_profile , self . entrypoint , & mut attrs) ?;
306+
307+ if attrs[ 0 ] . value == libva:: VA_ATTRIB_NOT_SUPPORTED || quality > attrs[ 0 ] . value {
308+ return Ok ( false ) ;
309+ }
310+ Ok ( true )
311+ }
312+
313+ pub ( crate ) fn supports_packed_header ( & self , header : u32 ) -> StatelessBackendResult < bool > {
314+ let display = self . context ( ) . display ( ) ;
315+ let mut attrs = [ libva:: VAConfigAttrib {
316+ type_ : libva:: VAConfigAttribType :: VAConfigAttribEncPackedHeaders ,
317+ value : 0 ,
318+ } ] ;
319+
320+ display. get_config_attributes ( self . va_profile , self . entrypoint , & mut attrs) ?;
321+
322+ if attrs[ 0 ] . value == libva:: VA_ATTRIB_NOT_SUPPORTED || ( header & attrs[ 0 ] . value ) == 0 {
323+ return Ok ( false ) ;
324+ }
325+ Ok ( true )
326+ }
274327}
275328
276329impl < M , Handle > StatelessEncoderBackendImport < Handle , Handle > for VaapiBackend < M , Handle >
@@ -491,6 +544,7 @@ pub(crate) mod tests {
491544 layout : self . frame_layout . clone ( ) ,
492545 force_keyframe : false ,
493546 timestamp : self . counter ,
547+ force_idr : false ,
494548 } ;
495549
496550 self . counter += 1 ;
0 commit comments