@ -153,114 +153,100 @@ static int vaapi_frames_get_constraints(AVHWDeviceContext *hwdev,
{
{
AVVAAPIDeviceContext * hwctx = hwdev - > hwctx ;
AVVAAPIDeviceContext * hwctx = hwdev - > hwctx ;
const AVVAAPIHWConfig * config = hwconfig ;
const AVVAAPIHWConfig * config = hwconfig ;
AVVAAPIHWConfig * tmp_config ;
VAAPIDeviceContext * ctx = hwdev - > internal - > priv ;
VASurfaceAttrib * attr_list = NULL ;
VASurfaceAttrib * attr_list = NULL ;
VAStatus vas ;
VAStatus vas ;
enum AVPixelFormat pix_fmt ;
enum AVPixelFormat pix_fmt ;
unsigned int fourcc ;
unsigned int fourcc ;
int err , i , j , attr_count , pix_fmt_count ;
int err , i , j , attr_count , pix_fmt_count ;
if ( ! hwconfig ) {
if ( config ) {
// No configuration was provided, so we create a temporary pipeline
attr_count = 0 ;
// configuration in order to query all supported image formats.
vas = vaQuerySurfaceAttributes ( hwctx - > display , config - > config_id ,
0 , & attr_count ) ;
tmp_config = av_mallocz ( sizeof ( * config ) ) ;
if ( ! tmp_config )
return AVERROR ( ENOMEM ) ;
vas = vaCreateConfig ( hwctx - > display ,
VAProfileNone , VAEntrypointVideoProc ,
NULL , 0 , & tmp_config - > config_id ) ;
if ( vas ! = VA_STATUS_SUCCESS ) {
if ( vas ! = VA_STATUS_SUCCESS ) {
// No vpp. We might still be able to do something useful if
av_log ( hwdev , AV_LOG_ERROR , " Failed to query surface attributes: "
// codecs are supported, so try to make the most-commonly
" %d (%s). \n " , vas , vaErrorStr ( vas ) ) ;
// supported decoder configuration we can to query instead.
err = AVERROR ( ENOSYS ) ;
vas = vaCreateConfig ( hwctx - > display ,
goto fail ;
VAProfileH264ConstrainedBaseline ,
VAEntrypointVLD , NULL , 0 ,
& tmp_config - > config_id ) ;
if ( vas ! = VA_STATUS_SUCCESS ) {
av_freep ( & tmp_config ) ;
return AVERROR ( ENOSYS ) ;
}
}
}
config = tmp_config ;
attr_list = av_malloc ( attr_count * sizeof ( * attr_list ) ) ;
}
if ( ! attr_list ) {
err = AVERROR ( ENOMEM ) ;
attr_count = 0 ;
goto fail ;
vas = vaQuerySurfaceAttributes ( hwctx - > display , config - > config_id ,
}
0 , & attr_count ) ;
if ( vas ! = VA_STATUS_SUCCESS ) {
av_log ( hwdev , AV_LOG_ERROR , " Failed to query surface attributes: "
" %d (%s). \n " , vas , vaErrorStr ( vas ) ) ;
err = AVERROR ( ENOSYS ) ;
goto fail ;
}
attr_list = av_malloc ( attr_count * sizeof ( * attr_list ) ) ;
vas = vaQuerySurfaceAttributes ( hwctx - > display , config - > config_id ,
if ( ! attr_list ) {
attr_list , & attr_count ) ;
err = AVERROR ( ENOMEM ) ;
if ( vas ! = VA_STATUS_SUCCESS ) {
goto fail ;
av_log ( hwdev , AV_LOG_ERROR , " Failed to query surface attributes: "
}
" %d (%s). \n " , vas , vaErrorStr ( vas ) ) ;
err = AVERROR ( ENOSYS ) ;
goto fail ;
}
vas = vaQuerySurfaceAttributes ( hwctx - > display , config - > config_id ,
pix_fmt_count = 0 ;
attr_list , & attr_count ) ;
for ( i = 0 ; i < attr_count ; i + + ) {
if ( vas ! = VA_STATUS_SUCCESS ) {
switch ( attr_list [ i ] . type ) {
av_log ( hwdev , AV_LOG_ERROR , " Failed to query surface attributes: "
case VASurfaceAttribPixelFormat :
" %d (%s). \n " , vas , vaErrorStr ( vas ) ) ;
fourcc = attr_list [ i ] . value . value . i ;
err = AVERROR ( ENOSYS ) ;
pix_fmt = vaapi_pix_fmt_from_fourcc ( fourcc ) ;
goto fail ;
if ( pix_fmt ! = AV_PIX_FMT_NONE ) {
}
+ + pix_fmt_count ;
} else {
// Something unsupported - ignore.
}
break ;
case VASurfaceAttribMinWidth :
constraints - > min_width = attr_list [ i ] . value . value . i ;
break ;
case VASurfaceAttribMinHeight :
constraints - > min_height = attr_list [ i ] . value . value . i ;
break ;
case VASurfaceAttribMaxWidth :
constraints - > max_width = attr_list [ i ] . value . value . i ;
break ;
case VASurfaceAttribMaxHeight :
constraints - > max_height = attr_list [ i ] . value . value . i ;
break ;
}
}
if ( pix_fmt_count = = 0 ) {
// Nothing usable found. Presumably there exists something which
// works, so leave the set null to indicate unknown.
constraints - > valid_sw_formats = NULL ;
} else {
constraints - > valid_sw_formats = av_malloc_array ( pix_fmt_count + 1 ,
sizeof ( pix_fmt ) ) ;
if ( ! constraints - > valid_sw_formats ) {
err = AVERROR ( ENOMEM ) ;
goto fail ;
}
pix_fmt_count = 0 ;
for ( i = j = 0 ; i < attr_count ; i + + ) {
for ( i = 0 ; i < attr_count ; i + + ) {
if ( attr_list [ i ] . type ! = VASurfaceAttribPixelFormat )
switch ( attr_list [ i ] . type ) {
continue ;
case VASurfaceAttribPixelFormat :
fourcc = attr_list [ i ] . value . value . i ;
fourcc = attr_list [ i ] . value . value . i ;
pix_fmt = vaapi_pix_fmt_from_fourcc ( fourcc ) ;
pix_fmt = vaapi_pix_fmt_from_fourcc ( fourcc ) ;
if ( pix_fmt ! = AV_PIX_FMT_NONE )
if ( pix_fmt ! = AV_PIX_FMT_NONE ) {
constraints - > valid_sw_formats [ j + + ] = pix_fmt ;
+ + pix_fmt_count ;
} else {
// Something unsupported - ignore.
}
}
break ;
av_assert0 ( j = = pix_fmt_count ) ;
case VASurfaceAttribMinWidth :
constraints - > valid_sw_formats [ j ] = AV_PIX_FMT_NONE ;
constraints - > min_width = attr_list [ i ] . value . value . i ;
break ;
case VASurfaceAttribMinHeight :
constraints - > min_height = attr_list [ i ] . value . value . i ;
break ;
case VASurfaceAttribMaxWidth :
constraints - > max_width = attr_list [ i ] . value . value . i ;
break ;
case VASurfaceAttribMaxHeight :
constraints - > max_height = attr_list [ i ] . value . value . i ;
break ;
}
}
}
if ( pix_fmt_count = = 0 ) {
// Nothing usable found. Presumably there exists something which
// works, so leave the set null to indicate unknown.
constraints - > valid_sw_formats = NULL ;
} else {
} else {
constraints - > valid_sw_formats = av_malloc_array ( pix_fmt_count + 1 ,
// No configuration supplied.
// Return the full set of image formats known by the implementation.
constraints - > valid_sw_formats = av_malloc_array ( ctx - > nb_formats + 1 ,
sizeof ( pix_fmt ) ) ;
sizeof ( pix_fmt ) ) ;
if ( ! constraints - > valid_sw_formats ) {
if ( ! constraints - > valid_sw_formats ) {
err = AVERROR ( ENOMEM ) ;
err = AVERROR ( ENOMEM ) ;
goto fail ;
goto fail ;
}
}
for ( i = 0 ; i < ctx - > nb_formats ; i + + )
for ( i = j = 0 ; i < attr_count ; i + + ) {
constraints - > valid_sw_formats [ i ] = ctx - > formats [ i ] . pix_fmt ;
if ( attr_list [ i ] . type ! = VASurfaceAttribPixelFormat )
constraints - > valid_sw_formats [ i ] = AV_PIX_FMT_NONE ;
continue ;
fourcc = attr_list [ i ] . value . value . i ;
pix_fmt = vaapi_pix_fmt_from_fourcc ( fourcc ) ;
if ( pix_fmt ! = AV_PIX_FMT_NONE )
constraints - > valid_sw_formats [ j + + ] = pix_fmt ;
}
av_assert0 ( j = = pix_fmt_count ) ;
constraints - > valid_sw_formats [ j ] = AV_PIX_FMT_NONE ;
}
}
constraints - > valid_hw_formats = av_malloc_array ( 2 , sizeof ( pix_fmt ) ) ;
constraints - > valid_hw_formats = av_malloc_array ( 2 , sizeof ( pix_fmt ) ) ;
@ -274,10 +260,6 @@ static int vaapi_frames_get_constraints(AVHWDeviceContext *hwdev,
err = 0 ;
err = 0 ;
fail :
fail :
av_freep ( & attr_list ) ;
av_freep ( & attr_list ) ;
if ( ! hwconfig ) {
vaDestroyConfig ( hwctx - > display , tmp_config - > config_id ) ;
av_freep ( & tmp_config ) ;
}
return err ;
return err ;
}
}
@ -285,21 +267,12 @@ static int vaapi_device_init(AVHWDeviceContext *hwdev)
{
{
VAAPIDeviceContext * ctx = hwdev - > internal - > priv ;
VAAPIDeviceContext * ctx = hwdev - > internal - > priv ;
AVVAAPIDeviceContext * hwctx = hwdev - > hwctx ;
AVVAAPIDeviceContext * hwctx = hwdev - > hwctx ;
AVHWFramesConstraints * constraints = NULL ;
VAImageFormat * image_list = NULL ;
VAImageFormat * image_list = NULL ;
VAStatus vas ;
VAStatus vas ;
int err , i , j , image_count ;
int err , i , image_count ;
enum AVPixelFormat pix_fmt ;
enum AVPixelFormat pix_fmt ;
unsigned int fourcc ;
unsigned int fourcc ;
constraints = av_mallocz ( sizeof ( * constraints ) ) ;
if ( ! constraints )
goto fail ;
err = vaapi_frames_get_constraints ( hwdev , NULL , constraints ) ;
if ( err < 0 )
goto fail ;
image_count = vaMaxNumImageFormats ( hwctx - > display ) ;
image_count = vaMaxNumImageFormats ( hwctx - > display ) ;
if ( image_count < = 0 ) {
if ( image_count < = 0 ) {
err = AVERROR ( EIO ) ;
err = AVERROR ( EIO ) ;
@ -325,28 +298,23 @@ static int vaapi_device_init(AVHWDeviceContext *hwdev)
for ( i = 0 ; i < image_count ; i + + ) {
for ( i = 0 ; i < image_count ; i + + ) {
fourcc = image_list [ i ] . fourcc ;
fourcc = image_list [ i ] . fourcc ;
pix_fmt = vaapi_pix_fmt_from_fourcc ( fourcc ) ;
pix_fmt = vaapi_pix_fmt_from_fourcc ( fourcc ) ;
for ( j = 0 ; constraints - > valid_sw_formats [ j ] ! = AV_PIX_FMT_NONE ; j + + ) {
if ( pix_fmt = = AV_PIX_FMT_NONE ) {
if ( pix_fmt = = constraints - > valid_sw_formats [ j ] )
av_log ( hwdev , AV_LOG_DEBUG , " Format %#x -> unknown. \n " ,
break ;
fourcc ) ;
}
} else {
if ( constraints - > valid_sw_formats [ j ] ! = AV_PIX_FMT_NONE ) {
av_log ( hwdev , AV_LOG_DEBUG , " Format %#x -> %s. \n " ,
av_log ( hwdev , AV_LOG_DEBUG , " Format %#x -> %s. \n " ,
fourcc , av_get_pix_fmt_name ( pix_fmt ) ) ;
fourcc , av_get_pix_fmt_name ( pix_fmt ) ) ;
ctx - > formats [ ctx - > nb_formats ] . pix_fmt = pix_fmt ;
ctx - > formats [ ctx - > nb_formats ] . pix_fmt = pix_fmt ;
ctx - > formats [ ctx - > nb_formats ] . image_format = image_list [ i ] ;
ctx - > formats [ ctx - > nb_formats ] . image_format = image_list [ i ] ;
+ + ctx - > nb_formats ;
+ + ctx - > nb_formats ;
} else {
av_log ( hwdev , AV_LOG_DEBUG , " Format %#x -> unknown. \n " , fourcc ) ;
}
}
}
}
av_free ( image_list ) ;
av_free ( image_list ) ;
av_hwframe_constraints_free ( & constraints ) ;
return 0 ;
return 0 ;
fail :
fail :
av_freep ( & ctx - > formats ) ;
av_freep ( & ctx - > formats ) ;
av_free ( image_list ) ;
av_free ( image_list ) ;
av_hwframe_constraints_free ( & constraints ) ;
return err ;
return err ;
}
}