@@ -392,8 +392,28 @@ impl DecoderInit {
392392 Ok ( ( ) ) => {
393393 self . first_frame = match frame. format ( ) {
394394 ffmpeg:: format:: Pixel :: VIDEOTOOLBOX => {
395+ let sw_format = unsafe {
396+ let ctx_ref = ( * self . decoder . as_ptr ( ) ) . hw_frames_ctx ;
397+ assert ! ( !ctx_ref. is_null( ) ) ;
398+
399+ let mut transfer_fmt_list = std:: ptr:: null_mut ( ) ;
400+ if ffmpeg_sys:: av_hwframe_transfer_get_formats (
401+ ctx_ref,
402+ ffmpeg_sys:: AVHWFrameTransferDirection :: AV_HWFRAME_TRANSFER_DIRECTION_FROM ,
403+ & mut transfer_fmt_list,
404+ 0 ) < 0
405+ {
406+ bail ! ( "call to av_hwframe_transfer_get_formats failed" ) ;
407+ } ;
408+
409+ let transfer_formats = read_format_list ( transfer_fmt_list) ;
410+ assert ! ( !transfer_formats. is_empty( ) ) ;
411+
412+ transfer_formats[ 0 ]
413+ } ;
414+
395415 let mut sw_frame = ffmpeg:: frame:: Video :: new (
396- ffmpeg :: format :: Pixel :: P010LE , // xxx
416+ sw_format ,
397417 self . decoder . width ( ) ,
398418 self . decoder . height ( ) ,
399419 ) ;
@@ -1025,38 +1045,51 @@ fn copy_frame(
10251045#[ no_mangle]
10261046unsafe extern "C" fn get_hw_format_videotoolbox (
10271047 ctx : * mut ffmpeg_sys:: AVCodecContext ,
1028- mut formats : * const ffmpeg_sys:: AVPixelFormat ,
1048+ list : * const ffmpeg_sys:: AVPixelFormat ,
10291049) -> ffmpeg_sys:: AVPixelFormat {
10301050 use ffmpeg_sys:: AVPixelFormat :: * ;
10311051
1032- while * formats != AV_PIX_FMT_NONE {
1033- if * formats == AV_PIX_FMT_VIDEOTOOLBOX {
1034- let frames_ctx_ref = ffmpeg_sys:: av_hwframe_ctx_alloc ( ( * ctx) . hw_device_ctx ) ;
1035- if frames_ctx_ref. is_null ( ) {
1036- error ! ( "call to av_hwframe_ctx_alloc failed" ) ;
1037- break ;
1038- }
1052+ let sw_pix_fmt = ( * ctx) . sw_pix_fmt ;
1053+ let formats = read_format_list ( list) ;
1054+
1055+ if formats. contains ( & ffmpeg:: format:: Pixel :: VIDEOTOOLBOX ) {
1056+ let frames_ctx_ref = ffmpeg_sys:: av_hwframe_ctx_alloc ( ( * ctx) . hw_device_ctx ) ;
1057+ if frames_ctx_ref. is_null ( ) {
1058+ error ! ( "call to av_hwframe_ctx_alloc failed" ) ;
1059+ return sw_pix_fmt;
1060+ }
10391061
1040- let frames_ctx = ( * frames_ctx_ref) . data as * mut ffmpeg_sys:: AVHWFramesContext ;
1041- ( * frames_ctx) . width = ( * ctx) . width ;
1042- ( * frames_ctx) . height = ( * ctx) . height ;
1043- ( * frames_ctx) . format = AV_PIX_FMT_VIDEOTOOLBOX ;
1044- ( * frames_ctx) . sw_format = ( * ctx) . sw_pix_fmt ;
1062+ debug ! ( ?formats, sw_pix_fmt = ?sw_pix_fmt, "get_hw_format_videotoolbox" ) ;
10451063
1046- let res = ffmpeg_sys:: av_hwframe_ctx_init ( frames_ctx_ref ) ;
1047- if res < 0 {
1048- error ! ( "call to av_hwframe_ctx_init failed" ) ;
1049- break ;
1050- }
1064+ let frames_ctx = ( * frames_ctx_ref ) . data as * mut ffmpeg_sys:: AVHWFramesContext ;
1065+ ( * frames_ctx ) . width = ( * ctx ) . width ;
1066+ ( * frames_ctx ) . height = ( * ctx ) . height ;
1067+ ( * frames_ctx ) . format = AV_PIX_FMT_VIDEOTOOLBOX ;
1068+ ( * frames_ctx ) . sw_format = AV_PIX_FMT_YUV420P ;
10511069
1052- debug ! ( "using VideoToolbox hardware encoder" ) ;
1053- ( * ctx) . hw_frames_ctx = frames_ctx_ref;
1054- return * formats;
1070+ let res = ffmpeg_sys:: av_hwframe_ctx_init ( frames_ctx_ref) ;
1071+ if res < 0 {
1072+ error ! ( "call to av_hwframe_ctx_init failed" ) ;
1073+ return sw_pix_fmt;
10551074 }
10561075
1057- formats = formats. add ( 1 ) ;
1076+ debug ! ( "using VideoToolbox hardware encoder" ) ;
1077+ ( * ctx) . hw_frames_ctx = frames_ctx_ref;
1078+ return AV_PIX_FMT_VIDEOTOOLBOX ;
1079+ }
1080+
1081+ warn ! ( "unable to determine ffmpeg hw format" ) ;
1082+ sw_pix_fmt
1083+ }
1084+
1085+ unsafe fn read_format_list (
1086+ mut ptr : * const ffmpeg_sys:: AVPixelFormat ,
1087+ ) -> Vec < ffmpeg:: format:: Pixel > {
1088+ let mut formats = Vec :: new ( ) ;
1089+ while !ptr. is_null ( ) && * ptr != ffmpeg_sys:: AVPixelFormat :: AV_PIX_FMT_NONE {
1090+ formats. push ( ( * ptr) . into ( ) ) ;
1091+ ptr = ptr. add ( 1 ) ;
10581092 }
10591093
1060- warn ! ( "VideoToolbox setup failed, falling back to CPU decoder" ) ;
1061- AV_PIX_FMT_YUV420P10LE
1094+ formats
10621095}
0 commit comments