@@ -295,6 +295,8 @@ cdef class VideoFrame(Frame):
295295 .. note:: For ``pal8``, an ``(image, palette)`` tuple will be returned,
296296 with the palette being in ARGB (PyAV will swap bytes if needed).
297297
298+ .. note:: For ``gbrp`` formats, channels are flipped to RGB order.
299+
298300 """
299301 cdef VideoFrame frame = self .reformat(** kwargs)
300302
@@ -312,29 +314,36 @@ cdef class VideoFrame(Frame):
312314 return np.hstack((
313315 useful_array(frame.planes[0 ]),
314316 useful_array(frame.planes[1 ]),
315- useful_array(frame.planes[2 ])
317+ useful_array(frame.planes[2 ]),
316318 )).reshape(- 1 , frame.height, frame.width)
317319 elif frame.format.name == " yuyv422" :
318320 assert frame.width % 2 == 0
319321 assert frame.height % 2 == 0
320322 return useful_array(frame.planes[0 ], 2 ).reshape(frame.height, frame.width, - 1 )
321323 elif frame.format.name == " gbrp" :
322324 array = np.empty((frame.height, frame.width, 3 ), dtype = " uint8" )
323- array[:, :, 0 ] = useful_array(frame.planes[2 ], 1 ).reshape(- 1 , frame.width)
324- array[:, :, 1 ] = useful_array(frame.planes[0 ], 1 ).reshape(- 1 , frame.width)
325- array[:, :, 2 ] = useful_array(frame.planes[1 ], 1 ).reshape(- 1 , frame.width)
325+ array[:, :, 0 ] = useful_array(frame.planes[2 ], 1 ).reshape(frame.height , frame.width)
326+ array[:, :, 1 ] = useful_array(frame.planes[0 ], 1 ).reshape(frame.height , frame.width)
327+ array[:, :, 2 ] = useful_array(frame.planes[1 ], 1 ).reshape(frame.height , frame.width)
326328 return array
327329 elif frame.format.name in (" gbrp10be" , " gbrp12be" , " gbrp14be" , " gbrp16be" , " gbrp10le" , " gbrp12le" , " gbrp14le" , " gbrp16le" ):
328330 array = np.empty((frame.height, frame.width, 3 ), dtype = " uint16" )
329- array[:, :, 0 ] = useful_array(frame.planes[2 ], 2 , " uint16" ).reshape(- 1 , frame.width)
330- array[:, :, 1 ] = useful_array(frame.planes[0 ], 2 , " uint16" ).reshape(- 1 , frame.width)
331- array[:, :, 2 ] = useful_array(frame.planes[1 ], 2 , " uint16" ).reshape(- 1 , frame.width)
331+ array[:, :, 0 ] = useful_array(frame.planes[2 ], 2 , " uint16" ).reshape(frame.height , frame.width)
332+ array[:, :, 1 ] = useful_array(frame.planes[0 ], 2 , " uint16" ).reshape(frame.height , frame.width)
333+ array[:, :, 2 ] = useful_array(frame.planes[1 ], 2 , " uint16" ).reshape(frame.height , frame.width)
332334 return byteswap_array(array, frame.format.name.endswith(" be" ))
333335 elif frame.format.name in (" gbrpf32be" , " gbrpf32le" ):
334336 array = np.empty((frame.height, frame.width, 3 ), dtype = " float32" )
335- array[:, :, 0 ] = useful_array(frame.planes[2 ], 4 , " float32" ).reshape(- 1 , frame.width)
336- array[:, :, 1 ] = useful_array(frame.planes[0 ], 4 , " float32" ).reshape(- 1 , frame.width)
337- array[:, :, 2 ] = useful_array(frame.planes[1 ], 4 , " float32" ).reshape(- 1 , frame.width)
337+ array[:, :, 0 ] = useful_array(frame.planes[2 ], 4 , " float32" ).reshape(frame.height, frame.width)
338+ array[:, :, 1 ] = useful_array(frame.planes[0 ], 4 , " float32" ).reshape(frame.height, frame.width)
339+ array[:, :, 2 ] = useful_array(frame.planes[1 ], 4 , " float32" ).reshape(frame.height, frame.width)
340+ return byteswap_array(array, frame.format.name.endswith(" be" ))
341+ elif frame.format.name in (" gbrapf32be" , " gbrapf32le" ):
342+ array = np.empty((frame.height, frame.width, 4 ), dtype = " float32" )
343+ array[:, :, 0 ] = useful_array(frame.planes[2 ], 4 , " float32" ).reshape(frame.height, frame.width)
344+ array[:, :, 1 ] = useful_array(frame.planes[0 ], 4 , " float32" ).reshape(frame.height, frame.width)
345+ array[:, :, 2 ] = useful_array(frame.planes[1 ], 4 , " float32" ).reshape(frame.height, frame.width)
346+ array[:, :, 3 ] = useful_array(frame.planes[3 ], 4 , " float32" ).reshape(frame.height, frame.width)
338347 return byteswap_array(array, frame.format.name.endswith(" be" ))
339348 elif frame.format.name in (" rgb24" , " bgr24" ):
340349 return useful_array(frame.planes[0 ], 3 ).reshape(frame.height, frame.width, - 1 )
@@ -345,17 +354,22 @@ cdef class VideoFrame(Frame):
345354 elif frame.format.name in (" gray16be" , " gray16le" ):
346355 return byteswap_array(
347356 useful_array(frame.planes[0 ], 2 , " uint16" ).reshape(frame.height, frame.width),
348- frame.format.name == " gray16be" ,
357+ frame.format.name.endswith(" be" ),
358+ )
359+ elif frame.format.name in (" grayf32be" , " grayf32le" ):
360+ return byteswap_array(
361+ useful_array(frame.planes[0 ], 4 , " float32" ).reshape(frame.height, frame.width),
362+ frame.format.name.endswith(" be" ),
349363 )
350364 elif frame.format.name in (" rgb48be" , " rgb48le" ):
351365 return byteswap_array(
352366 useful_array(frame.planes[0 ], 6 , " uint16" ).reshape(frame.height, frame.width, - 1 ),
353- frame.format.name == " rgb48be " ,
367+ frame.format.name.endswith( " be " ) ,
354368 )
355369 elif frame.format.name in (" rgba64be" , " rgba64le" ):
356370 return byteswap_array(
357371 useful_array(frame.planes[0 ], 8 , " uint16" ).reshape(frame.height, frame.width, - 1 ),
358- frame.format.name == " rgba64be " ,
372+ frame.format.name.endswith( " be " ) ,
359373 )
360374 elif frame.format.name == " pal8" :
361375 image = useful_array(frame.planes[0 ]).reshape(frame.height, frame.width)
@@ -491,6 +505,8 @@ cdef class VideoFrame(Frame):
491505 must be in the system's native byte order.
492506
493507 .. note:: for ``pal8``, an ``(image, palette)`` pair must be passed. `palette` must have shape (256, 4) and is given in ARGB format (PyAV will swap bytes if needed).
508+
509+ .. note:: for ``gbrp`` formats, channels are assumed to be given in RGB order.
494510 """
495511 if format == " pal8" :
496512 array, palette = array
@@ -568,19 +584,34 @@ cdef class VideoFrame(Frame):
568584 elif format in (" gray16be" , " gray16le" ):
569585 check_ndarray(array, " uint16" , 2 )
570586 frame = VideoFrame(array.shape[1 ], array.shape[0 ], format)
571- copy_array_to_plane(byteswap_array(array, format == " gray16be" ), frame.planes[0 ], 2 )
587+ copy_array_to_plane(byteswap_array(array, format.endswith(" be" )), frame.planes[0 ], 2 )
588+ return frame
589+ elif format in (" grayf32be" , " grayf32le" ):
590+ check_ndarray(array, " float32" , 2 )
591+ frame = VideoFrame(array.shape[1 ], array.shape[0 ], format)
592+ copy_array_to_plane(byteswap_array(array, format.endswith(" be" )), frame.planes[0 ], 4 )
572593 return frame
573594 elif format in (" rgb48be" , " rgb48le" ):
574595 check_ndarray(array, " uint16" , 3 )
575596 check_ndarray_shape(array, array.shape[2 ] == 3 )
576597 frame = VideoFrame(array.shape[1 ], array.shape[0 ], format)
577- copy_array_to_plane(byteswap_array(array, format == " rgb48be " ), frame.planes[0 ], 6 )
598+ copy_array_to_plane(byteswap_array(array, format.endswith( " be " ) ), frame.planes[0 ], 6 )
578599 return frame
579600 elif format in (" rgba64be" , " rgba64le" ):
580601 check_ndarray(array, " uint16" , 3 )
581602 check_ndarray_shape(array, array.shape[2 ] == 4 )
582603 frame = VideoFrame(array.shape[1 ], array.shape[0 ], format)
583- copy_array_to_plane(byteswap_array(array, format == " rgba64be" ), frame.planes[0 ], 8 )
604+ copy_array_to_plane(byteswap_array(array, format.endswith(" be" )), frame.planes[0 ], 8 )
605+ return frame
606+ elif format in (" gbrapf32be" , " gbrapf32le" ):
607+ check_ndarray(array, " float32" , 3 )
608+ check_ndarray_shape(array, array.shape[2 ] == 4 )
609+
610+ frame = VideoFrame(array.shape[1 ], array.shape[0 ], format)
611+ copy_array_to_plane(byteswap_array(array[:, :, 1 ], format.endswith(" be" )), frame.planes[0 ], 4 )
612+ copy_array_to_plane(byteswap_array(array[:, :, 2 ], format.endswith(" be" )), frame.planes[1 ], 4 )
613+ copy_array_to_plane(byteswap_array(array[:, :, 0 ], format.endswith(" be" )), frame.planes[2 ], 4 )
614+ copy_array_to_plane(byteswap_array(array[:, :, 3 ], format.endswith(" be" )), frame.planes[3 ], 4 )
584615 return frame
585616 elif format == " nv12" :
586617 check_ndarray(array, " uint8" , 2 )
0 commit comments