@ -26,6 +26,7 @@
# include "libavutil/opt.h"
# include "libavutil/eval.h"
# include "libavutil/hwcontext.h"
# include "libavutil/hwcontext_qsv.h"
# include "libavutil/pixdesc.h"
# include "libavutil/mathematics.h"
@ -139,8 +140,9 @@ static const AVOption options[] = {
{ " height " , " Output video height " , OFFSET ( oh ) , AV_OPT_TYPE_STRING , { . str = " w*ch/cw " } , 0 , 255 , . flags = FLAGS } ,
{ " format " , " Output pixel format " , OFFSET ( output_format_str ) , AV_OPT_TYPE_STRING , { . str = " same " } , . flags = FLAGS } ,
{ " async_depth " , " Internal parallelization depth, the higher the value the higher the latency. " , OFFSET ( async_depth ) , AV_OPT_TYPE_INT , { . i64 = 0 } , 0 , INT_MAX , . flags = FLAGS } ,
# ifdef QSV_HAVE_SCALING_CONFIG
{ " scale_mode " , " scale mode: 0=auto, 1=low power, 2=high quality " , OFFSET ( scale_mode ) , AV_OPT_TYPE_INT , { . i64 = MFX_SCALING_MODE_DEFAULT } , MFX_SCALING_MODE_DEFAULT , MFX_SCALING_MODE_QUALITY , . flags = FLAGS , " scale mode " } ,
# endif
{ NULL }
} ;
@ -297,6 +299,32 @@ static int config_input(AVFilterLink *inlink)
return 0 ;
}
static mfxStatus get_mfx_version ( const AVFilterContext * ctx , mfxVersion * mfx_version )
{
const AVFilterLink * inlink = ctx - > inputs [ 0 ] ;
AVBufferRef * device_ref ;
AVHWDeviceContext * device_ctx ;
AVQSVDeviceContext * device_hwctx ;
if ( inlink - > hw_frames_ctx ) {
AVHWFramesContext * frames_ctx = ( AVHWFramesContext * ) inlink - > hw_frames_ctx - > data ;
device_ref = frames_ctx - > device_ref ;
} else if ( ctx - > hw_device_ctx ) {
device_ref = ctx - > hw_device_ctx ;
} else {
// Unavailable hw context doesn't matter in pass-through mode,
// so don't error here but let runtime version checks fail by setting to 0.0
mfx_version - > Major = 0 ;
mfx_version - > Minor = 0 ;
return MFX_ERR_NONE ;
}
device_ctx = ( AVHWDeviceContext * ) device_ref - > data ;
device_hwctx = device_ctx - > hwctx ;
return MFXQueryVersion ( device_hwctx - > session , mfx_version ) ;
}
static int config_output ( AVFilterLink * outlink )
{
AVFilterContext * ctx = outlink - > src ;
@ -304,6 +332,7 @@ static int config_output(AVFilterLink *outlink)
QSVVPPParam param = { NULL } ;
QSVVPPCrop crop = { 0 } ;
mfxExtBuffer * ext_buf [ ENH_FILTERS_COUNT ] ;
mfxVersion mfx_version ;
AVFilterLink * inlink = ctx - > inputs [ 0 ] ;
enum AVPixelFormat in_format ;
@ -317,6 +346,11 @@ static int config_output(AVFilterLink *outlink)
param . ext_buf = ext_buf ;
param . async_depth = vpp - > async_depth ;
if ( get_mfx_version ( ctx , & mfx_version ) ! = MFX_ERR_NONE ) {
av_log ( ctx , AV_LOG_ERROR , " Failed to query mfx version. \n " ) ;
return AVERROR ( EINVAL ) ;
}
if ( inlink - > format = = AV_PIX_FMT_QSV ) {
if ( ! inlink - > hw_frames_ctx | | ! inlink - > hw_frames_ctx - > data )
return AVERROR ( EINVAL ) ;
@ -467,19 +501,20 @@ static int config_output(AVFilterLink *outlink)
# endif
}
if ( inlink - > w ! = outlink - > w | | inlink - > h ! = outlink - > h ) {
# ifdef QSV_HAVE_SCALING_CONFIG
memset ( & vpp - > scale_conf , 0 , sizeof ( mfxExtVPPScaling ) ) ;
vpp - > scale_conf . Header . BufferId = MFX_EXTBUFF_VPP_SCALING ;
vpp - > scale_conf . Header . BufferSz = sizeof ( mfxExtVPPScaling ) ;
vpp - > scale_conf . ScalingMode = vpp - > scale_mode ;
param . ext_buf [ param . num_ext_buf + + ] = ( mfxExtBuffer * ) & vpp - > scale_conf ;
# else
av_log ( ctx , AV_LOG_WARNING , " The QSV VPP Scale option is "
" not supported with this MSDK version. \n " ) ;
# endif
if ( inlink - > w ! = outlink - > w | | inlink - > h ! = outlink - > h ) {
if ( QSV_RUNTIME_VERSION_ATLEAST ( mfx_version , 1 , 19 ) ) {
memset ( & vpp - > scale_conf , 0 , sizeof ( mfxExtVPPScaling ) ) ;
vpp - > scale_conf . Header . BufferId = MFX_EXTBUFF_VPP_SCALING ;
vpp - > scale_conf . Header . BufferSz = sizeof ( mfxExtVPPScaling ) ;
vpp - > scale_conf . ScalingMode = vpp - > scale_mode ;
param . ext_buf [ param . num_ext_buf + + ] = ( mfxExtBuffer * ) & vpp - > scale_conf ;
} else
av_log ( ctx , AV_LOG_WARNING , " The QSV VPP Scale option is "
" not supported with this MSDK version. \n " ) ;
}
# endif
if ( vpp - > use_frc | | vpp - > use_crop | | vpp - > deinterlace | | vpp - > denoise | |
vpp - > detail | | vpp - > procamp | | vpp - > rotate | | vpp - > hflip | |