@@ -235,14 +235,16 @@ fn swizzled_view(tex: &metal::TextureRef, swizzle: [u8; 4]) -> metal::Texture {
235235/// Le swizzle du plan Y qui porte la matrice de la frame, ou `None` pour BT.709 (aussi le
236236/// défaut d'un flux non tagué). La matrice vient de `AVFrame::colorspace`, que libavcodec lit
237237/// dans le VUI : VideoToolbox ne pose pas `kCVImageBufferYCbCrMatrixKey` sur ses buffers.
238- unsafe fn matrix_swizzle ( frame : * const AVFrame ) -> Option < [ u8 ; 4 ] > {
239- match ( * frame) . colorspace {
238+ /// BT.2020 CL n'est pas une simple matrice : il garde le défaut plutôt qu'un rendu NCL faux.
239+ ///
240+ /// Alpha à 0 : échantillons 10 bits (P010), que `yuv_matrix` convertit avec les bornes 10 bits.
241+ fn matrix_swizzle ( colorspace : AVColorSpace :: Type , ten_bit : bool ) -> Option < [ u8 ; 4 ] > {
242+ let depth = if ten_bit { SWZ_ZERO } else { SWZ_ONE } ;
243+ match colorspace {
240244 AVColorSpace :: AVCOL_SPC_BT470BG | AVColorSpace :: AVCOL_SPC_SMPTE170M => {
241- Some ( [ SWZ_RED , SWZ_ONE , SWZ_ZERO , SWZ_ONE ] )
242- }
243- AVColorSpace :: AVCOL_SPC_BT2020_NCL | AVColorSpace :: AVCOL_SPC_BT2020_CL => {
244- Some ( [ SWZ_RED , SWZ_ZERO , SWZ_ONE , SWZ_ONE ] )
245+ Some ( [ SWZ_RED , SWZ_ONE , SWZ_ZERO , depth] )
245246 }
247+ AVColorSpace :: AVCOL_SPC_BT2020_NCL => Some ( [ SWZ_RED , SWZ_ZERO , SWZ_ONE , depth] ) ,
246248 _ => None ,
247249 }
248250}
@@ -1230,7 +1232,8 @@ impl Compositor {
12301232 } ;
12311233 let mut y = cache. make_texture_from_pixel_buffer ( pb, 0 , y_fmt) ?;
12321234 let mut uv = cache. make_texture_from_pixel_buffer ( pb, 1 , uv_fmt) ?;
1233- if let Some ( swizzle) = matrix_swizzle ( frame) {
1235+ let ten_bit = matches ! ( pixel_format, CV_420_10_BIPLANAR_VIDEO | CV_420_10_BIPLANAR_FULL ) ;
1236+ if let Some ( swizzle) = matrix_swizzle ( ( * frame) . colorspace , ten_bit) {
12341237 y = swizzled_view ( & y, swizzle) ;
12351238 }
12361239 if matches ! ( pixel_format, CV_420_8_BIPLANAR_FULL | CV_420_10_BIPLANAR_FULL ) {
@@ -5451,4 +5454,19 @@ mod tests {
54515454 crate :: shader_fx:: compile_metal ( & gpu. device , & code, & params) . expect ( "compile" ) ;
54525455 eprintln ! ( "recompilation d'une source déjà vue : {:.1} ms" , t0. elapsed( ) . as_secs_f64( ) * 1000.0 ) ;
54535456 }
5457+
5458+ #[ test]
5459+ fn matrix_swizzle_marks_matrix_and_depth ( ) {
5460+ use AVColorSpace :: * ;
5461+ assert_eq ! (
5462+ matrix_swizzle( AVCOL_SPC_SMPTE170M , false ) ,
5463+ Some ( [ SWZ_RED , SWZ_ONE , SWZ_ZERO , SWZ_ONE ] )
5464+ ) ;
5465+ assert_eq ! (
5466+ matrix_swizzle( AVCOL_SPC_BT2020_NCL , true ) ,
5467+ Some ( [ SWZ_RED , SWZ_ZERO , SWZ_ONE , SWZ_ZERO ] )
5468+ ) ;
5469+ assert_eq ! ( matrix_swizzle( AVCOL_SPC_BT709 , false ) , None ) ;
5470+ assert_eq ! ( matrix_swizzle( AVCOL_SPC_BT2020_CL , true ) , None ) ;
5471+ }
54545472}
0 commit comments