2017-08-24 02:16:28 +00:00
/*
2017-11-11 17:46:24 +00:00
* This file is part of FFmpeg .
2017-08-24 02:16:28 +00:00
*
2017-11-11 17:46:24 +00:00
* FFmpeg is free software ; you can redistribute it and / or
2017-08-24 02:16:28 +00:00
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation ; either
* version 2.1 of the License , or ( at your option ) any later version .
*
2017-11-11 17:46:24 +00:00
* FFmpeg is distributed in the hope that it will be useful ,
2017-08-24 02:16:28 +00:00
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Lesser General Public License for more details .
*
* You should have received a copy of the GNU Lesser General Public
2017-11-11 17:46:24 +00:00
* License along with FFmpeg ; if not , write to the Free Software
2017-08-24 02:16:28 +00:00
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA
*/
/**
* * @ file
* * Hardware accelerated common filters based on Intel Quick Sync Video VPP
* */
# include <float.h>
2023-01-17 06:20:26 +00:00
# include "config_components.h"
2017-08-24 02:16:28 +00:00
# include "libavutil/opt.h"
# include "libavutil/eval.h"
2021-08-01 23:06:25 +00:00
# include "libavutil/hwcontext.h"
2022-01-07 07:01:31 +00:00
# include "libavutil/hwcontext_qsv.h"
2017-08-24 02:16:28 +00:00
# include "libavutil/pixdesc.h"
2018-04-04 09:51:30 +00:00
# include "libavutil/mathematics.h"
2017-08-24 02:16:28 +00:00
# include "formats.h"
# include "internal.h"
# include "avfilter.h"
2021-03-31 02:07:44 +00:00
# include "filters.h"
2017-08-24 02:16:28 +00:00
# include "qsvvpp.h"
lavf/vf_vpp_qsv: add support for QSV transpose filter
Add transpose support for qsv_vpp with rotate and hflip:
- rotate: [0, 3] support clockwise rotation of 0, 90, 180, 270;
- hflip: [0, 1] support horizontal flip;
Configure with:
{"cclock_hflip","clock","cclock","clock_hflip","reversal","hflip","vflip"}
CMD:
ffmpeg -hwaccel qsv -c:v h264_qsv -i input.h264
-vf 'format=qsv,vpp_qsv=transpose=clock' -c:v h264_qsv output.h264
ffmpeg -init_hw_device qsv=hw -filter_hw_device hw -c:v h264_qsv -i input.h264
-vf 'hwupload=extra_hw_frames=64,format=qsv,vpp_qsv=transpose=cclock_hflip'
-f rawvideo -pix_fmt nv12 ./transpose.yuv
Signed-off-by: Linjie Fu <linjie.fu@intel.com>
Signed-off-by: Zhong Li <zhong.li@intel.com>
2019-07-10 17:57:46 +00:00
# include "transpose.h"
2017-08-24 02:16:28 +00:00
# define OFFSET(x) offsetof(VPPContext, x)
2017-11-12 17:07:45 +00:00
# define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM)
2017-08-24 02:16:28 +00:00
/* number of video enhancement filters */
2021-08-04 00:24:47 +00:00
# define ENH_FILTERS_COUNT (8)
2017-08-24 02:16:28 +00:00
typedef struct VPPContext {
2023-01-09 07:12:10 +00:00
QSVVPPContext qsv ;
2017-08-24 02:16:28 +00:00
/* Video Enhancement Algorithms */
mfxExtVPPDeinterlacing deinterlace_conf ;
mfxExtVPPFrameRateConversion frc_conf ;
mfxExtVPPDenoise denoise_conf ;
mfxExtVPPDetail detail_conf ;
mfxExtVPPProcAmp procamp_conf ;
lavf/vf_vpp_qsv: add support for QSV transpose filter
Add transpose support for qsv_vpp with rotate and hflip:
- rotate: [0, 3] support clockwise rotation of 0, 90, 180, 270;
- hflip: [0, 1] support horizontal flip;
Configure with:
{"cclock_hflip","clock","cclock","clock_hflip","reversal","hflip","vflip"}
CMD:
ffmpeg -hwaccel qsv -c:v h264_qsv -i input.h264
-vf 'format=qsv,vpp_qsv=transpose=clock' -c:v h264_qsv output.h264
ffmpeg -init_hw_device qsv=hw -filter_hw_device hw -c:v h264_qsv -i input.h264
-vf 'hwupload=extra_hw_frames=64,format=qsv,vpp_qsv=transpose=cclock_hflip'
-f rawvideo -pix_fmt nv12 ./transpose.yuv
Signed-off-by: Linjie Fu <linjie.fu@intel.com>
Signed-off-by: Zhong Li <zhong.li@intel.com>
2019-07-10 17:57:46 +00:00
mfxExtVPPRotation rotation_conf ;
mfxExtVPPMirroring mirroring_conf ;
2021-02-24 01:41:58 +00:00
mfxExtVPPScaling scale_conf ;
2017-08-24 02:16:28 +00:00
2023-01-09 07:12:05 +00:00
/**
* New dimensions . Special values are :
* 0 = original width / height
* - 1 = keep original aspect
*/
2017-08-24 02:16:28 +00:00
int out_width ;
int out_height ;
2019-05-31 00:44:47 +00:00
/**
* Output sw format . AV_PIX_FMT_NONE for no conversion .
*/
enum AVPixelFormat out_format ;
2017-08-24 02:16:28 +00:00
AVRational framerate ; /* target framerate */
int use_frc ; /* use framerate conversion */
int deinterlace ; /* deinterlace mode : 0=off, 1=bob, 2=advanced */
int denoise ; /* Enable Denoise algorithm. Value [0, 100] */
int detail ; /* Enable Detail Enhancement algorithm. */
/* Level is the optional, value [0, 100] */
int use_crop ; /* 1 = use crop; 0=none */
int crop_w ;
int crop_h ;
int crop_x ;
int crop_y ;
lavf/vf_vpp_qsv: add support for QSV transpose filter
Add transpose support for qsv_vpp with rotate and hflip:
- rotate: [0, 3] support clockwise rotation of 0, 90, 180, 270;
- hflip: [0, 1] support horizontal flip;
Configure with:
{"cclock_hflip","clock","cclock","clock_hflip","reversal","hflip","vflip"}
CMD:
ffmpeg -hwaccel qsv -c:v h264_qsv -i input.h264
-vf 'format=qsv,vpp_qsv=transpose=clock' -c:v h264_qsv output.h264
ffmpeg -init_hw_device qsv=hw -filter_hw_device hw -c:v h264_qsv -i input.h264
-vf 'hwupload=extra_hw_frames=64,format=qsv,vpp_qsv=transpose=cclock_hflip'
-f rawvideo -pix_fmt nv12 ./transpose.yuv
Signed-off-by: Linjie Fu <linjie.fu@intel.com>
Signed-off-by: Zhong Li <zhong.li@intel.com>
2019-07-10 17:57:46 +00:00
int transpose ;
int rotate ; /* rotate angle : [0, 90, 180, 270] */
int hflip ; /* flip mode : 0 = off, 1 = HORIZONTAL flip */
2021-02-24 01:41:58 +00:00
int scale_mode ; /* scale mode : 0 = auto, 1 = low power, 2 = high quality */
2017-08-24 02:16:28 +00:00
/* param for the procamp */
int procamp ; /* enable procamp */
float hue ;
float saturation ;
float contrast ;
float brightness ;
char * cx , * cy , * cw , * ch ;
char * ow , * oh ;
2019-05-31 00:44:47 +00:00
char * output_format_str ;
2021-03-31 02:07:44 +00:00
2023-01-09 07:12:07 +00:00
int has_passthrough ; /* apply pass through mode if possible */
2023-01-30 01:37:17 +00:00
int field_rate ; /* Generate output at frame rate or field rate for deinterlace mode, 0: frame, 1: field */
2017-08-24 02:16:28 +00:00
} VPPContext ;
static const char * const var_names [ ] = {
" iw " , " in_w " ,
" ih " , " in_h " ,
" ow " , " out_w " , " w " ,
" oh " , " out_h " , " h " ,
" cw " ,
" ch " ,
" cx " ,
" cy " ,
2023-01-09 07:12:03 +00:00
" a " , " dar " ,
" sar " ,
2017-08-24 02:16:28 +00:00
NULL
} ;
enum var_name {
2023-01-09 07:12:03 +00:00
VAR_IW , VAR_IN_W ,
VAR_IH , VAR_IN_H ,
VAR_OW , VAR_OUT_W , VAR_W ,
VAR_OH , VAR_OUT_H , VAR_H ,
VAR_CW ,
VAR_CH ,
VAR_CX ,
VAR_CY ,
VAR_A , VAR_DAR ,
VAR_SAR ,
2017-08-24 02:16:28 +00:00
VAR_VARS_NB
} ;
static int eval_expr ( AVFilterContext * ctx )
{
# define PASS_EXPR(e, s) {\
2023-01-09 07:12:04 +00:00
if ( s ) { \
ret = av_expr_parse ( & e , s , var_names , NULL , NULL , NULL , NULL , 0 , ctx ) ; \
if ( ret < 0 ) { \
av_log ( ctx , AV_LOG_ERROR , " Error when passing '%s'. \n " , s ) ; \
goto release ; \
} \
2017-08-24 02:16:28 +00:00
} \
}
2023-01-09 07:12:04 +00:00
# define CALC_EXPR(e, v, i, d) {\
if ( e ) \
i = v = av_expr_eval ( e , var_values , NULL ) ; \
else \
i = v = d ; \
2017-08-24 02:16:28 +00:00
}
VPPContext * vpp = ctx - > priv ;
double var_values [ VAR_VARS_NB ] = { NAN } ;
AVExpr * w_expr = NULL , * h_expr = NULL ;
AVExpr * cw_expr = NULL , * ch_expr = NULL ;
AVExpr * cx_expr = NULL , * cy_expr = NULL ;
int ret = 0 ;
PASS_EXPR ( cw_expr , vpp - > cw ) ;
PASS_EXPR ( ch_expr , vpp - > ch ) ;
PASS_EXPR ( w_expr , vpp - > ow ) ;
PASS_EXPR ( h_expr , vpp - > oh ) ;
PASS_EXPR ( cx_expr , vpp - > cx ) ;
PASS_EXPR ( cy_expr , vpp - > cy ) ;
2023-01-09 07:12:03 +00:00
var_values [ VAR_IW ] =
2017-08-24 02:16:28 +00:00
var_values [ VAR_IN_W ] = ctx - > inputs [ 0 ] - > w ;
2023-01-09 07:12:03 +00:00
var_values [ VAR_IH ] =
2017-08-24 02:16:28 +00:00
var_values [ VAR_IN_H ] = ctx - > inputs [ 0 ] - > h ;
2023-01-09 07:12:03 +00:00
var_values [ VAR_A ] = ( double ) var_values [ VAR_IN_W ] / var_values [ VAR_IN_H ] ;
var_values [ VAR_SAR ] = ctx - > inputs [ 0 ] - > sample_aspect_ratio . num ?
( double ) ctx - > inputs [ 0 ] - > sample_aspect_ratio . num / ctx - > inputs [ 0 ] - > sample_aspect_ratio . den : 1 ;
var_values [ VAR_DAR ] = var_values [ VAR_A ] * var_values [ VAR_SAR ] ;
2017-08-24 02:16:28 +00:00
/* crop params */
2023-01-09 07:12:04 +00:00
CALC_EXPR ( cw_expr , var_values [ VAR_CW ] , vpp - > crop_w , var_values [ VAR_IW ] ) ;
CALC_EXPR ( ch_expr , var_values [ VAR_CH ] , vpp - > crop_h , var_values [ VAR_IH ] ) ;
2017-08-24 02:16:28 +00:00
/* calc again in case cw is relative to ch */
2023-01-09 07:12:04 +00:00
CALC_EXPR ( cw_expr , var_values [ VAR_CW ] , vpp - > crop_w , var_values [ VAR_IW ] ) ;
2017-08-24 02:16:28 +00:00
CALC_EXPR ( w_expr ,
2023-01-09 07:12:03 +00:00
var_values [ VAR_OUT_W ] = var_values [ VAR_OW ] = var_values [ VAR_W ] ,
2023-01-09 07:12:04 +00:00
vpp - > out_width , var_values [ VAR_CW ] ) ;
2017-08-24 02:16:28 +00:00
CALC_EXPR ( h_expr ,
2023-01-09 07:12:03 +00:00
var_values [ VAR_OUT_H ] = var_values [ VAR_OH ] = var_values [ VAR_H ] ,
2023-01-09 07:12:04 +00:00
vpp - > out_height , var_values [ VAR_CH ] ) ;
2017-08-24 02:16:28 +00:00
/* calc again in case ow is relative to oh */
CALC_EXPR ( w_expr ,
2023-01-09 07:12:03 +00:00
var_values [ VAR_OUT_W ] = var_values [ VAR_OW ] = var_values [ VAR_W ] ,
2023-01-09 07:12:04 +00:00
vpp - > out_width , var_values [ VAR_CW ] ) ;
2017-08-24 02:16:28 +00:00
2023-01-09 07:12:04 +00:00
CALC_EXPR ( cx_expr , var_values [ VAR_CX ] , vpp - > crop_x , ( var_values [ VAR_IW ] - var_values [ VAR_OW ] ) / 2 ) ;
CALC_EXPR ( cy_expr , var_values [ VAR_CY ] , vpp - > crop_y , ( var_values [ VAR_IH ] - var_values [ VAR_OH ] ) / 2 ) ;
2017-08-24 02:16:28 +00:00
/* calc again in case cx is relative to cy */
2023-01-09 07:12:04 +00:00
CALC_EXPR ( cx_expr , var_values [ VAR_CX ] , vpp - > crop_x , ( var_values [ VAR_IW ] - var_values [ VAR_OW ] ) / 2 ) ;
2017-08-24 02:16:28 +00:00
2023-01-09 07:12:03 +00:00
if ( ( vpp - > crop_w ! = var_values [ VAR_IW ] ) | | ( vpp - > crop_h ! = var_values [ VAR_IH ] ) )
2017-08-24 02:16:28 +00:00
vpp - > use_crop = 1 ;
release :
av_expr_free ( w_expr ) ;
av_expr_free ( h_expr ) ;
av_expr_free ( cw_expr ) ;
av_expr_free ( ch_expr ) ;
av_expr_free ( cx_expr ) ;
av_expr_free ( cy_expr ) ;
# undef PASS_EXPR
# undef CALC_EXPR
return ret ;
}
2023-01-09 07:12:06 +00:00
static av_cold int vpp_preinit ( AVFilterContext * ctx )
{
VPPContext * vpp = ctx - > priv ;
/* For AV_OPT_TYPE_STRING options, NULL is handled in other way so
* we needn ' t set default value here
*/
vpp - > saturation = 1.0 ;
vpp - > contrast = 1.0 ;
vpp - > transpose = - 1 ;
2023-01-09 07:12:07 +00:00
vpp - > has_passthrough = 1 ;
2023-01-09 07:12:06 +00:00
return 0 ;
}
2019-05-31 00:44:47 +00:00
static av_cold int vpp_init ( AVFilterContext * ctx )
{
VPPContext * vpp = ctx - > priv ;
2023-01-09 07:12:08 +00:00
if ( ! vpp - > output_format_str | | ! strcmp ( vpp - > output_format_str , " same " ) ) {
2019-05-31 00:44:47 +00:00
vpp - > out_format = AV_PIX_FMT_NONE ;
} else {
vpp - > out_format = av_get_pix_fmt ( vpp - > output_format_str ) ;
if ( vpp - > out_format = = AV_PIX_FMT_NONE ) {
av_log ( ctx , AV_LOG_ERROR , " Unrecognized output pixel format: %s \n " , vpp - > output_format_str ) ;
return AVERROR ( EINVAL ) ;
}
}
return 0 ;
}
2017-08-24 02:16:28 +00:00
static int config_input ( AVFilterLink * inlink )
{
AVFilterContext * ctx = inlink - > dst ;
VPPContext * vpp = ctx - > priv ;
int ret ;
2023-01-09 07:12:05 +00:00
int64_t ow , oh ;
2017-08-24 02:16:28 +00:00
2023-01-30 01:37:17 +00:00
if ( vpp - > framerate . den = = 0 | | vpp - > framerate . num = = 0 ) {
2017-08-24 02:16:28 +00:00
vpp - > framerate = inlink - > frame_rate ;
2023-01-30 01:37:17 +00:00
if ( vpp - > deinterlace & & vpp - > field_rate )
vpp - > framerate = av_mul_q ( inlink - > frame_rate ,
( AVRational ) { 2 , 1 } ) ;
}
2017-08-24 02:16:28 +00:00
if ( av_cmp_q ( vpp - > framerate , inlink - > frame_rate ) )
vpp - > use_frc = 1 ;
ret = eval_expr ( ctx ) ;
if ( ret ! = 0 ) {
av_log ( ctx , AV_LOG_ERROR , " Fail to eval expr. \n " ) ;
return ret ;
}
2023-01-09 07:12:05 +00:00
ow = vpp - > out_width ;
oh = vpp - > out_height ;
/* sanity check params */
if ( ow < - 1 | | oh < - 1 ) {
av_log ( ctx , AV_LOG_ERROR , " Size values less than -1 are not acceptable. \n " ) ;
return AVERROR ( EINVAL ) ;
2017-08-24 02:16:28 +00:00
}
2023-01-09 07:12:05 +00:00
if ( ow = = - 1 & & oh = = - 1 )
vpp - > out_width = vpp - > out_height = 0 ;
if ( ! ( ow = vpp - > out_width ) )
ow = inlink - > w ;
if ( ! ( oh = vpp - > out_height ) )
oh = inlink - > h ;
if ( ow = = - 1 )
ow = av_rescale ( oh , inlink - > w , inlink - > h ) ;
if ( oh = = - 1 )
oh = av_rescale ( ow , inlink - > h , inlink - > w ) ;
if ( ow > INT_MAX | | oh > INT_MAX | |
( oh * inlink - > w ) > INT_MAX | |
( ow * inlink - > h ) > INT_MAX )
av_log ( ctx , AV_LOG_ERROR , " Rescaled value for width or height is too big. \n " ) ;
vpp - > out_width = ow ;
vpp - > out_height = oh ;
2017-08-24 02:16:28 +00:00
if ( vpp - > use_crop ) {
vpp - > crop_x = FFMAX ( vpp - > crop_x , 0 ) ;
vpp - > crop_y = FFMAX ( vpp - > crop_y , 0 ) ;
if ( vpp - > crop_w + vpp - > crop_x > inlink - > w )
vpp - > crop_x = inlink - > w - vpp - > crop_w ;
if ( vpp - > crop_h + vpp - > crop_y > inlink - > h )
vpp - > crop_y = inlink - > h - vpp - > crop_h ;
}
return 0 ;
}
2022-01-07 07:01:31 +00:00
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 ) ;
}
2017-08-24 02:16:28 +00:00
static int config_output ( AVFilterLink * outlink )
{
AVFilterContext * ctx = outlink - > src ;
VPPContext * vpp = ctx - > priv ;
QSVVPPParam param = { NULL } ;
QSVVPPCrop crop = { 0 } ;
mfxExtBuffer * ext_buf [ ENH_FILTERS_COUNT ] ;
2022-01-07 07:01:31 +00:00
mfxVersion mfx_version ;
2018-04-04 09:51:30 +00:00
AVFilterLink * inlink = ctx - > inputs [ 0 ] ;
2019-05-31 00:44:47 +00:00
enum AVPixelFormat in_format ;
2017-08-24 02:16:28 +00:00
outlink - > w = vpp - > out_width ;
outlink - > h = vpp - > out_height ;
outlink - > frame_rate = vpp - > framerate ;
2023-01-30 01:37:17 +00:00
outlink - > time_base = av_inv_q ( vpp - > framerate ) ;
2017-08-24 02:16:28 +00:00
param . filter_frame = NULL ;
param . num_ext_buf = 0 ;
param . ext_buf = ext_buf ;
2022-01-07 07:01:31 +00:00
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 ) ;
}
2019-05-31 00:44:47 +00:00
if ( inlink - > format = = AV_PIX_FMT_QSV ) {
if ( ! inlink - > hw_frames_ctx | | ! inlink - > hw_frames_ctx - > data )
return AVERROR ( EINVAL ) ;
else
in_format = ( ( AVHWFramesContext * ) inlink - > hw_frames_ctx - > data ) - > sw_format ;
} else
in_format = inlink - > format ;
2019-08-15 02:33:57 +00:00
if ( vpp - > out_format = = AV_PIX_FMT_NONE )
vpp - > out_format = in_format ;
param . out_sw_format = vpp - > out_format ;
2019-05-31 00:44:47 +00:00
2017-08-24 02:16:28 +00:00
if ( vpp - > use_crop ) {
crop . in_idx = 0 ;
crop . x = vpp - > crop_x ;
crop . y = vpp - > crop_y ;
crop . w = vpp - > crop_w ;
crop . h = vpp - > crop_h ;
param . num_crop = 1 ;
param . crop = & crop ;
}
2022-12-05 06:25:08 +00:00
# define INIT_MFX_EXTBUF(extbuf, id) do { \
memset ( & vpp - > extbuf , 0 , sizeof ( vpp - > extbuf ) ) ; \
vpp - > extbuf . Header . BufferId = id ; \
vpp - > extbuf . Header . BufferSz = sizeof ( vpp - > extbuf ) ; \
param . ext_buf [ param . num_ext_buf + + ] = ( mfxExtBuffer * ) & vpp - > extbuf ; \
} while ( 0 )
# define SET_MFX_PARAM_FIELD(extbuf, field, value) do { \
vpp - > extbuf . field = value ; \
} while ( 0 )
2017-08-24 02:16:28 +00:00
2022-12-05 06:25:08 +00:00
if ( vpp - > deinterlace ) {
INIT_MFX_EXTBUF ( deinterlace_conf , MFX_EXTBUFF_VPP_DEINTERLACING ) ;
SET_MFX_PARAM_FIELD ( deinterlace_conf , Mode , ( vpp - > deinterlace = = 1 ?
MFX_DEINTERLACING_BOB : MFX_DEINTERLACING_ADVANCED ) ) ;
2017-08-24 02:16:28 +00:00
}
if ( vpp - > use_frc ) {
2022-12-05 06:25:08 +00:00
INIT_MFX_EXTBUF ( frc_conf , MFX_EXTBUFF_VPP_FRAME_RATE_CONVERSION ) ;
SET_MFX_PARAM_FIELD ( frc_conf , Algorithm , MFX_FRCALGM_DISTRIBUTED_TIMESTAMP ) ;
2017-08-24 02:16:28 +00:00
}
if ( vpp - > denoise ) {
2022-12-05 06:25:08 +00:00
INIT_MFX_EXTBUF ( denoise_conf , MFX_EXTBUFF_VPP_DENOISE ) ;
SET_MFX_PARAM_FIELD ( denoise_conf , DenoiseFactor , vpp - > denoise ) ;
2017-08-24 02:16:28 +00:00
}
if ( vpp - > detail ) {
2022-12-05 06:25:08 +00:00
INIT_MFX_EXTBUF ( detail_conf , MFX_EXTBUFF_VPP_DETAIL ) ;
SET_MFX_PARAM_FIELD ( detail_conf , DetailFactor , vpp - > detail ) ;
2017-08-24 02:16:28 +00:00
}
if ( vpp - > procamp ) {
2022-12-05 06:25:08 +00:00
INIT_MFX_EXTBUF ( procamp_conf , MFX_EXTBUFF_VPP_PROCAMP ) ;
SET_MFX_PARAM_FIELD ( procamp_conf , Hue , vpp - > hue ) ;
SET_MFX_PARAM_FIELD ( procamp_conf , Saturation , vpp - > saturation ) ;
SET_MFX_PARAM_FIELD ( procamp_conf , Contrast , vpp - > contrast ) ;
SET_MFX_PARAM_FIELD ( procamp_conf , Brightness , vpp - > brightness ) ;
2017-08-24 02:16:28 +00:00
}
lavf/vf_vpp_qsv: add support for QSV transpose filter
Add transpose support for qsv_vpp with rotate and hflip:
- rotate: [0, 3] support clockwise rotation of 0, 90, 180, 270;
- hflip: [0, 1] support horizontal flip;
Configure with:
{"cclock_hflip","clock","cclock","clock_hflip","reversal","hflip","vflip"}
CMD:
ffmpeg -hwaccel qsv -c:v h264_qsv -i input.h264
-vf 'format=qsv,vpp_qsv=transpose=clock' -c:v h264_qsv output.h264
ffmpeg -init_hw_device qsv=hw -filter_hw_device hw -c:v h264_qsv -i input.h264
-vf 'hwupload=extra_hw_frames=64,format=qsv,vpp_qsv=transpose=cclock_hflip'
-f rawvideo -pix_fmt nv12 ./transpose.yuv
Signed-off-by: Linjie Fu <linjie.fu@intel.com>
Signed-off-by: Zhong Li <zhong.li@intel.com>
2019-07-10 17:57:46 +00:00
if ( vpp - > transpose > = 0 ) {
2022-05-22 12:19:11 +00:00
if ( QSV_RUNTIME_VERSION_ATLEAST ( mfx_version , 1 , 17 ) ) {
switch ( vpp - > transpose ) {
case TRANSPOSE_CCLOCK_FLIP :
vpp - > rotate = MFX_ANGLE_270 ;
vpp - > hflip = MFX_MIRRORING_HORIZONTAL ;
break ;
case TRANSPOSE_CLOCK :
vpp - > rotate = MFX_ANGLE_90 ;
vpp - > hflip = MFX_MIRRORING_DISABLED ;
break ;
case TRANSPOSE_CCLOCK :
vpp - > rotate = MFX_ANGLE_270 ;
vpp - > hflip = MFX_MIRRORING_DISABLED ;
break ;
case TRANSPOSE_CLOCK_FLIP :
vpp - > rotate = MFX_ANGLE_90 ;
vpp - > hflip = MFX_MIRRORING_HORIZONTAL ;
break ;
case TRANSPOSE_REVERSAL :
vpp - > rotate = MFX_ANGLE_180 ;
vpp - > hflip = MFX_MIRRORING_DISABLED ;
break ;
case TRANSPOSE_HFLIP :
vpp - > rotate = MFX_ANGLE_0 ;
vpp - > hflip = MFX_MIRRORING_HORIZONTAL ;
break ;
case TRANSPOSE_VFLIP :
vpp - > rotate = MFX_ANGLE_180 ;
vpp - > hflip = MFX_MIRRORING_HORIZONTAL ;
break ;
default :
av_log ( ctx , AV_LOG_ERROR , " Failed to set transpose mode to %d. \n " , vpp - > transpose ) ;
return AVERROR ( EINVAL ) ;
}
} else {
av_log ( ctx , AV_LOG_WARNING , " The QSV VPP transpose option is "
" not supported with this MSDK version. \n " ) ;
vpp - > transpose = 0 ;
lavf/vf_vpp_qsv: add support for QSV transpose filter
Add transpose support for qsv_vpp with rotate and hflip:
- rotate: [0, 3] support clockwise rotation of 0, 90, 180, 270;
- hflip: [0, 1] support horizontal flip;
Configure with:
{"cclock_hflip","clock","cclock","clock_hflip","reversal","hflip","vflip"}
CMD:
ffmpeg -hwaccel qsv -c:v h264_qsv -i input.h264
-vf 'format=qsv,vpp_qsv=transpose=clock' -c:v h264_qsv output.h264
ffmpeg -init_hw_device qsv=hw -filter_hw_device hw -c:v h264_qsv -i input.h264
-vf 'hwupload=extra_hw_frames=64,format=qsv,vpp_qsv=transpose=cclock_hflip'
-f rawvideo -pix_fmt nv12 ./transpose.yuv
Signed-off-by: Linjie Fu <linjie.fu@intel.com>
Signed-off-by: Zhong Li <zhong.li@intel.com>
2019-07-10 17:57:46 +00:00
}
}
if ( vpp - > rotate ) {
2022-05-22 12:19:11 +00:00
if ( QSV_RUNTIME_VERSION_ATLEAST ( mfx_version , 1 , 17 ) ) {
2022-12-05 06:25:08 +00:00
INIT_MFX_EXTBUF ( rotation_conf , MFX_EXTBUFF_VPP_ROTATION ) ;
SET_MFX_PARAM_FIELD ( rotation_conf , Angle , vpp - > rotate ) ;
2022-05-22 12:19:11 +00:00
if ( MFX_ANGLE_90 = = vpp - > rotate | | MFX_ANGLE_270 = = vpp - > rotate ) {
FFSWAP ( int , vpp - > out_width , vpp - > out_height ) ;
FFSWAP ( int , outlink - > w , outlink - > h ) ;
av_log ( ctx , AV_LOG_DEBUG , " Swap width and height for clock/cclock rotation. \n " ) ;
}
} else {
av_log ( ctx , AV_LOG_WARNING , " The QSV VPP rotate option is "
" not supported with this MSDK version. \n " ) ;
vpp - > rotate = 0 ;
lavf/vf_vpp_qsv: add support for QSV transpose filter
Add transpose support for qsv_vpp with rotate and hflip:
- rotate: [0, 3] support clockwise rotation of 0, 90, 180, 270;
- hflip: [0, 1] support horizontal flip;
Configure with:
{"cclock_hflip","clock","cclock","clock_hflip","reversal","hflip","vflip"}
CMD:
ffmpeg -hwaccel qsv -c:v h264_qsv -i input.h264
-vf 'format=qsv,vpp_qsv=transpose=clock' -c:v h264_qsv output.h264
ffmpeg -init_hw_device qsv=hw -filter_hw_device hw -c:v h264_qsv -i input.h264
-vf 'hwupload=extra_hw_frames=64,format=qsv,vpp_qsv=transpose=cclock_hflip'
-f rawvideo -pix_fmt nv12 ./transpose.yuv
Signed-off-by: Linjie Fu <linjie.fu@intel.com>
Signed-off-by: Zhong Li <zhong.li@intel.com>
2019-07-10 17:57:46 +00:00
}
}
if ( vpp - > hflip ) {
2022-05-22 12:19:11 +00:00
if ( QSV_RUNTIME_VERSION_ATLEAST ( mfx_version , 1 , 19 ) ) {
2022-12-05 06:25:08 +00:00
INIT_MFX_EXTBUF ( mirroring_conf , MFX_EXTBUFF_VPP_MIRRORING ) ;
SET_MFX_PARAM_FIELD ( mirroring_conf , Type , vpp - > hflip ) ;
2022-05-22 12:19:11 +00:00
} else {
av_log ( ctx , AV_LOG_WARNING , " The QSV VPP hflip option is "
" not supported with this MSDK version. \n " ) ;
vpp - > hflip = 0 ;
}
lavf/vf_vpp_qsv: add support for QSV transpose filter
Add transpose support for qsv_vpp with rotate and hflip:
- rotate: [0, 3] support clockwise rotation of 0, 90, 180, 270;
- hflip: [0, 1] support horizontal flip;
Configure with:
{"cclock_hflip","clock","cclock","clock_hflip","reversal","hflip","vflip"}
CMD:
ffmpeg -hwaccel qsv -c:v h264_qsv -i input.h264
-vf 'format=qsv,vpp_qsv=transpose=clock' -c:v h264_qsv output.h264
ffmpeg -init_hw_device qsv=hw -filter_hw_device hw -c:v h264_qsv -i input.h264
-vf 'hwupload=extra_hw_frames=64,format=qsv,vpp_qsv=transpose=cclock_hflip'
-f rawvideo -pix_fmt nv12 ./transpose.yuv
Signed-off-by: Linjie Fu <linjie.fu@intel.com>
Signed-off-by: Zhong Li <zhong.li@intel.com>
2019-07-10 17:57:46 +00:00
}
2022-11-28 04:43:21 +00:00
if ( inlink - > w ! = outlink - > w | | inlink - > h ! = outlink - > h | | in_format ! = vpp - > out_format ) {
2022-01-07 07:01:31 +00:00
if ( QSV_RUNTIME_VERSION_ATLEAST ( mfx_version , 1 , 19 ) ) {
2022-07-28 03:16:08 +00:00
int mode = vpp - > scale_mode ;
# if QSV_ONEVPL
if ( mode > 2 )
mode = MFX_SCALING_MODE_VENDOR + mode - 2 ;
# endif
2022-12-05 06:25:08 +00:00
INIT_MFX_EXTBUF ( scale_conf , MFX_EXTBUFF_VPP_SCALING ) ;
2022-07-28 03:16:08 +00:00
SET_MFX_PARAM_FIELD ( scale_conf , ScalingMode , mode ) ;
2022-01-07 07:01:31 +00:00
} else
2022-11-28 04:43:21 +00:00
av_log ( ctx , AV_LOG_WARNING , " The QSV VPP Scale & format conversion "
" option is not supported with this MSDK version. \n " ) ;
2021-02-24 01:41:58 +00:00
}
2022-12-05 06:25:08 +00:00
# undef INIT_MFX_EXTBUF
# undef SET_MFX_PARAM_FIELD
2018-04-04 09:51:30 +00:00
if ( vpp - > use_frc | | vpp - > use_crop | | vpp - > deinterlace | | vpp - > denoise | |
lavf/vf_vpp_qsv: add support for QSV transpose filter
Add transpose support for qsv_vpp with rotate and hflip:
- rotate: [0, 3] support clockwise rotation of 0, 90, 180, 270;
- hflip: [0, 1] support horizontal flip;
Configure with:
{"cclock_hflip","clock","cclock","clock_hflip","reversal","hflip","vflip"}
CMD:
ffmpeg -hwaccel qsv -c:v h264_qsv -i input.h264
-vf 'format=qsv,vpp_qsv=transpose=clock' -c:v h264_qsv output.h264
ffmpeg -init_hw_device qsv=hw -filter_hw_device hw -c:v h264_qsv -i input.h264
-vf 'hwupload=extra_hw_frames=64,format=qsv,vpp_qsv=transpose=cclock_hflip'
-f rawvideo -pix_fmt nv12 ./transpose.yuv
Signed-off-by: Linjie Fu <linjie.fu@intel.com>
Signed-off-by: Zhong Li <zhong.li@intel.com>
2019-07-10 17:57:46 +00:00
vpp - > detail | | vpp - > procamp | | vpp - > rotate | | vpp - > hflip | |
2023-01-09 07:12:07 +00:00
inlink - > w ! = outlink - > w | | inlink - > h ! = outlink - > h | | in_format ! = vpp - > out_format | |
! vpp - > has_passthrough )
2023-01-09 07:12:10 +00:00
return ff_qsvvpp_init ( ctx , & param ) ;
2018-04-04 09:51:30 +00:00
else {
2023-01-09 07:12:10 +00:00
/* No MFX session is created in this case */
2018-04-04 09:51:30 +00:00
av_log ( ctx , AV_LOG_VERBOSE , " qsv vpp pass through mode. \n " ) ;
if ( inlink - > hw_frames_ctx )
outlink - > hw_frames_ctx = av_buffer_ref ( inlink - > hw_frames_ctx ) ;
}
return 0 ;
2017-08-24 02:16:28 +00:00
}
2021-03-31 02:07:44 +00:00
static int activate ( AVFilterContext * ctx )
2017-08-24 02:16:28 +00:00
{
2021-03-31 02:07:44 +00:00
AVFilterLink * inlink = ctx - > inputs [ 0 ] ;
AVFilterLink * outlink = ctx - > outputs [ 0 ] ;
2023-01-09 07:12:10 +00:00
QSVVPPContext * qsv = ctx - > priv ;
2021-03-31 02:07:44 +00:00
AVFrame * in = NULL ;
2021-09-15 05:15:18 +00:00
int ret , status = 0 ;
int64_t pts = AV_NOPTS_VALUE ;
2021-03-31 02:07:44 +00:00
FF_FILTER_FORWARD_STATUS_BACK ( outlink , inlink ) ;
2023-01-09 07:12:10 +00:00
if ( ! qsv - > eof ) {
2021-03-31 02:07:44 +00:00
ret = ff_inlink_consume_frame ( inlink , & in ) ;
if ( ret < 0 )
return ret ;
if ( ff_inlink_acknowledge_status ( inlink , & status , & pts ) ) {
if ( status = = AVERROR_EOF ) {
2023-01-09 07:12:10 +00:00
qsv - > eof = 1 ;
2021-03-31 02:07:44 +00:00
}
}
}
2023-01-09 07:12:10 +00:00
if ( qsv - > session ) {
if ( in | | qsv - > eof ) {
2021-03-31 02:07:44 +00:00
ret = ff_qsvvpp_filter_frame ( qsv , inlink , in ) ;
av_frame_free ( & in ) ;
2022-05-12 01:18:21 +00:00
if ( ret = = AVERROR ( EAGAIN ) )
goto not_ready ;
else if ( ret < 0 )
return ret ;
2021-03-31 02:07:44 +00:00
2023-01-09 07:12:10 +00:00
if ( qsv - > eof )
2022-05-12 01:18:21 +00:00
goto eof ;
2021-03-31 02:07:44 +00:00
if ( qsv - > got_frame ) {
qsv - > got_frame = 0 ;
2022-05-12 01:18:21 +00:00
return 0 ;
2021-03-31 02:07:44 +00:00
}
}
2018-04-03 01:50:20 +00:00
} else {
2023-01-09 07:12:10 +00:00
/* No MFX session is created in pass-through mode */
2021-03-31 02:07:44 +00:00
if ( in ) {
if ( in - > pts ! = AV_NOPTS_VALUE )
in - > pts = av_rescale_q ( in - > pts , inlink - > time_base , outlink - > time_base ) ;
ret = ff_filter_frame ( outlink , in ) ;
2022-05-12 01:18:21 +00:00
if ( ret < 0 )
return ret ;
2023-01-09 07:12:10 +00:00
if ( qsv - > eof )
2022-05-12 01:18:21 +00:00
goto eof ;
return 0 ;
2021-03-31 02:07:44 +00:00
}
2018-04-04 09:51:30 +00:00
}
2017-08-24 02:16:28 +00:00
2022-05-12 01:18:21 +00:00
not_ready :
2023-01-09 07:12:10 +00:00
if ( qsv - > eof )
2022-05-12 01:18:21 +00:00
goto eof ;
FF_FILTER_FORWARD_WANTED ( outlink , inlink ) ;
2021-03-31 02:07:44 +00:00
return FFERROR_NOT_READY ;
2022-05-12 01:18:21 +00:00
eof :
2023-03-16 02:20:52 +00:00
pts = av_rescale_q ( pts , inlink - > time_base , outlink - > time_base ) ;
2022-05-12 01:18:21 +00:00
ff_outlink_set_status ( outlink , status , pts ) ;
return 0 ;
2017-08-24 02:16:28 +00:00
}
2023-01-17 06:20:26 +00:00
static av_cold void vpp_uninit ( AVFilterContext * ctx )
{
ff_qsvvpp_close ( ctx ) ;
}
static const AVFilterPad vpp_inputs [ ] = {
{
. name = " default " ,
. type = AVMEDIA_TYPE_VIDEO ,
. config_props = config_input ,
. get_buffer . video = ff_qsvvpp_get_video_buffer ,
} ,
} ;
static const AVFilterPad vpp_outputs [ ] = {
{
. name = " default " ,
. type = AVMEDIA_TYPE_VIDEO ,
. config_props = config_output ,
} ,
} ;
2023-01-17 06:20:27 +00:00
# define DEFINE_QSV_FILTER(x, sn, ln, fmts) \
static const AVClass x # # _class = { \
. class_name = # sn " _qsv " , \
. item_name = av_default_item_name , \
. option = x # # _options , \
. version = LIBAVUTIL_VERSION_INT , \
} ; \
const AVFilter ff_vf_ # # sn # # _qsv = { \
. name = # sn " _qsv " , \
. description = NULL_IF_CONFIG_SMALL ( " Quick Sync Video " # ln ) , \
. preinit = x # # _preinit , \
. init = vpp_init , \
. uninit = vpp_uninit , \
. priv_size = sizeof ( VPPContext ) , \
. priv_class = & x # # _class , \
FILTER_INPUTS ( vpp_inputs ) , \
FILTER_OUTPUTS ( vpp_outputs ) , \
fmts , \
. activate = activate , \
. flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE , \
2023-03-15 17:57:36 +00:00
. flags = AVFILTER_FLAG_HWDEVICE , \
2023-01-17 06:20:27 +00:00
} ;
2017-08-24 02:16:28 +00:00
2023-01-17 06:20:27 +00:00
# if CONFIG_VPP_QSV_FILTER
2017-08-24 02:16:28 +00:00
2023-01-17 06:20:27 +00:00
static const AVOption vpp_options [ ] = {
2023-01-17 06:20:26 +00:00
{ " deinterlace " , " deinterlace mode: 0=off, 1=bob, 2=advanced " , OFFSET ( deinterlace ) , AV_OPT_TYPE_INT , { . i64 = 0 } , 0 , MFX_DEINTERLACING_ADVANCED , . flags = FLAGS , " deinterlace " } ,
{ " bob " , " Bob deinterlace mode. " , 0 , AV_OPT_TYPE_CONST , { . i64 = MFX_DEINTERLACING_BOB } , . flags = FLAGS , " deinterlace " } ,
{ " advanced " , " Advanced deinterlace mode. " , 0 , AV_OPT_TYPE_CONST , { . i64 = MFX_DEINTERLACING_ADVANCED } , . flags = FLAGS , " deinterlace " } ,
{ " denoise " , " denoise level [0, 100] " , OFFSET ( denoise ) , AV_OPT_TYPE_INT , { . i64 = 0 } , 0 , 100 , . flags = FLAGS } ,
{ " detail " , " enhancement level [0, 100] " , OFFSET ( detail ) , AV_OPT_TYPE_INT , { . i64 = 0 } , 0 , 100 , . flags = FLAGS } ,
{ " framerate " , " output framerate " , OFFSET ( framerate ) , AV_OPT_TYPE_RATIONAL , { . dbl = 0.0 } , 0 , DBL_MAX , . flags = FLAGS } ,
{ " procamp " , " Enable ProcAmp " , OFFSET ( procamp ) , AV_OPT_TYPE_INT , { . i64 = 0 } , 0 , 1 , . flags = FLAGS } ,
{ " hue " , " ProcAmp hue " , OFFSET ( hue ) , AV_OPT_TYPE_FLOAT , { . dbl = 0.0 } , - 180.0 , 180.0 , . flags = FLAGS } ,
{ " saturation " , " ProcAmp saturation " , OFFSET ( saturation ) , AV_OPT_TYPE_FLOAT , { . dbl = 1.0 } , 0.0 , 10.0 , . flags = FLAGS } ,
{ " contrast " , " ProcAmp contrast " , OFFSET ( contrast ) , AV_OPT_TYPE_FLOAT , { . dbl = 1.0 } , 0.0 , 10.0 , . flags = FLAGS } ,
{ " brightness " , " ProcAmp brightness " , OFFSET ( brightness ) , AV_OPT_TYPE_FLOAT , { . dbl = 0.0 } , - 100.0 , 100.0 , . flags = FLAGS } ,
{ " transpose " , " set transpose direction " , OFFSET ( transpose ) , AV_OPT_TYPE_INT , { . i64 = - 1 } , - 1 , 6 , FLAGS , " transpose " } ,
{ " cclock_hflip " , " rotate counter-clockwise with horizontal flip " , 0 , AV_OPT_TYPE_CONST , { . i64 = TRANSPOSE_CCLOCK_FLIP } , . flags = FLAGS , . unit = " transpose " } ,
{ " clock " , " rotate clockwise " , 0 , AV_OPT_TYPE_CONST , { . i64 = TRANSPOSE_CLOCK } , . flags = FLAGS , . unit = " transpose " } ,
{ " cclock " , " rotate counter-clockwise " , 0 , AV_OPT_TYPE_CONST , { . i64 = TRANSPOSE_CCLOCK } , . flags = FLAGS , . unit = " transpose " } ,
{ " clock_hflip " , " rotate clockwise with horizontal flip " , 0 , AV_OPT_TYPE_CONST , { . i64 = TRANSPOSE_CLOCK_FLIP } , . flags = FLAGS , . unit = " transpose " } ,
{ " reversal " , " rotate by half-turn " , 0 , AV_OPT_TYPE_CONST , { . i64 = TRANSPOSE_REVERSAL } , . flags = FLAGS , . unit = " transpose " } ,
{ " hflip " , " flip horizontally " , 0 , AV_OPT_TYPE_CONST , { . i64 = TRANSPOSE_HFLIP } , . flags = FLAGS , . unit = " transpose " } ,
{ " vflip " , " flip vertically " , 0 , AV_OPT_TYPE_CONST , { . i64 = TRANSPOSE_VFLIP } , . flags = FLAGS , . unit = " transpose " } ,
{ " cw " , " set the width crop area expression " , OFFSET ( cw ) , AV_OPT_TYPE_STRING , { . str = " iw " } , 0 , 0 , FLAGS } ,
{ " ch " , " set the height crop area expression " , OFFSET ( ch ) , AV_OPT_TYPE_STRING , { . str = " ih " } , 0 , 0 , FLAGS } ,
{ " cx " , " set the x crop area expression " , OFFSET ( cx ) , AV_OPT_TYPE_STRING , { . str = " (in_w-out_w)/2 " } , 0 , 0 , FLAGS } ,
{ " cy " , " set the y crop area expression " , OFFSET ( cy ) , AV_OPT_TYPE_STRING , { . str = " (in_h-out_h)/2 " } , 0 , 0 , FLAGS } ,
{ " w " , " Output video width(0=input video width, -1=keep input video aspect) " , OFFSET ( ow ) , AV_OPT_TYPE_STRING , { . str = " cw " } , 0 , 255 , . flags = FLAGS } ,
{ " width " , " Output video width(0=input video width, -1=keep input video aspect) " , OFFSET ( ow ) , AV_OPT_TYPE_STRING , { . str = " cw " } , 0 , 255 , . flags = FLAGS } ,
{ " h " , " Output video height(0=input video height, -1=keep input video aspect) " , OFFSET ( oh ) , AV_OPT_TYPE_STRING , { . str = " w*ch/cw " } , 0 , 255 , . flags = FLAGS } ,
{ " height " , " Output video height(0=input video height, -1=keep input video aspect) " , 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 ( qsv . async_depth ) , AV_OPT_TYPE_INT , { . i64 = 0 } , 0 , INT_MAX , . flags = FLAGS } ,
2022-07-28 03:16:08 +00:00
# if QSV_ONEVPL
{ " scale_mode " , " scaling & format conversion mode (mode compute(3), vd(4) and ve(5) are only available on some platforms) " , OFFSET ( scale_mode ) , AV_OPT_TYPE_INT , { . i64 = 0 } , 0 , 5 , . flags = FLAGS , " scale mode " } ,
# else
{ " scale_mode " , " scaling & format conversion mode " , 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
2023-01-17 06:20:26 +00:00
{ " auto " , " auto mode " , 0 , AV_OPT_TYPE_CONST , { . i64 = MFX_SCALING_MODE_DEFAULT } , INT_MIN , INT_MAX , FLAGS , " scale mode " } ,
{ " low_power " , " low power mode " , 0 , AV_OPT_TYPE_CONST , { . i64 = MFX_SCALING_MODE_LOWPOWER } , INT_MIN , INT_MAX , FLAGS , " scale mode " } ,
{ " hq " , " high quality mode " , 0 , AV_OPT_TYPE_CONST , { . i64 = MFX_SCALING_MODE_QUALITY } , INT_MIN , INT_MAX , FLAGS , " scale mode " } ,
2022-07-28 03:16:08 +00:00
# if QSV_ONEVPL
{ " compute " , " compute " , 0 , AV_OPT_TYPE_CONST , { . i64 = 3 } , INT_MIN , INT_MAX , FLAGS , " scale mode " } ,
{ " vd " , " vd " , 0 , AV_OPT_TYPE_CONST , { . i64 = 4 } , INT_MIN , INT_MAX , FLAGS , " scale mode " } ,
{ " ve " , " ve " , 0 , AV_OPT_TYPE_CONST , { . i64 = 5 } , INT_MIN , INT_MAX , FLAGS , " scale mode " } ,
# endif
2023-01-17 06:20:26 +00:00
2023-01-30 01:37:17 +00:00
{ " rate " , " Generate output at frame rate or field rate, available only for deinterlace mode " ,
OFFSET ( field_rate ) , AV_OPT_TYPE_INT , { . i64 = 0 } , 0 , 1 , FLAGS , " rate " } ,
{ " frame " , " Output at frame rate (one frame of output for each field-pair) " ,
0 , AV_OPT_TYPE_CONST , { . i64 = 0 } , 0 , 0 , FLAGS , " rate " } ,
{ " field " , " Output at field rate (one frame of output for each field) " ,
0 , AV_OPT_TYPE_CONST , { . i64 = 1 } , 0 , 0 , FLAGS , " rate " } ,
2023-01-17 06:20:26 +00:00
{ NULL }
} ;
2017-08-24 02:16:28 +00:00
2023-01-17 06:20:27 +00:00
static int vpp_query_formats ( AVFilterContext * ctx )
{
lavfi/vf_vpp_qsv: only add the given output sw format to output pad
Otherwise the output format is not changed when output is in system
memory. For example, the output format is still p010le in the following
case:
$ ffmpeg -qsv_device /dev/dri/renderD128 -f lavfi -i testsrc -vf
"format=p010le,vpp_qsv=extra_hw_frames=8:format=nv12" -f null -
...
Output #0, null, to 'pipe:':
Metadata:
encoder : Lavf60.4.100
Stream #0:0: Video: wrapped_avframe, p010le(tv, progressive), 320x240
[SAR 1:1 DAR 4:3], q=2-31, 200 kb/s, 25 fps, 25 tbn
Signed-off-by: Haihao Xiang <haihao.xiang@intel.com>
2023-03-08 05:10:48 +00:00
VPPContext * vpp = ctx - > priv ;
int ret , i = 0 ;
2023-01-17 06:20:27 +00:00
static const enum AVPixelFormat in_pix_fmts [ ] = {
AV_PIX_FMT_YUV420P ,
AV_PIX_FMT_NV12 ,
AV_PIX_FMT_YUYV422 ,
AV_PIX_FMT_RGB32 ,
AV_PIX_FMT_P010 ,
2022-03-10 06:39:06 +00:00
# if CONFIG_VAAPI
AV_PIX_FMT_UYVY422 ,
# endif
2023-01-17 06:20:27 +00:00
AV_PIX_FMT_QSV ,
AV_PIX_FMT_NONE
} ;
lavfi/vf_vpp_qsv: only add the given output sw format to output pad
Otherwise the output format is not changed when output is in system
memory. For example, the output format is still p010le in the following
case:
$ ffmpeg -qsv_device /dev/dri/renderD128 -f lavfi -i testsrc -vf
"format=p010le,vpp_qsv=extra_hw_frames=8:format=nv12" -f null -
...
Output #0, null, to 'pipe:':
Metadata:
encoder : Lavf60.4.100
Stream #0:0: Video: wrapped_avframe, p010le(tv, progressive), 320x240
[SAR 1:1 DAR 4:3], q=2-31, 200 kb/s, 25 fps, 25 tbn
Signed-off-by: Haihao Xiang <haihao.xiang@intel.com>
2023-03-08 05:10:48 +00:00
static enum AVPixelFormat out_pix_fmts [ 4 ] ;
2017-08-24 02:16:28 +00:00
2023-01-17 06:20:27 +00:00
ret = ff_formats_ref ( ff_make_format_list ( in_pix_fmts ) ,
& ctx - > inputs [ 0 ] - > outcfg . formats ) ;
if ( ret < 0 )
return ret ;
lavfi/vf_vpp_qsv: only add the given output sw format to output pad
Otherwise the output format is not changed when output is in system
memory. For example, the output format is still p010le in the following
case:
$ ffmpeg -qsv_device /dev/dri/renderD128 -f lavfi -i testsrc -vf
"format=p010le,vpp_qsv=extra_hw_frames=8:format=nv12" -f null -
...
Output #0, null, to 'pipe:':
Metadata:
encoder : Lavf60.4.100
Stream #0:0: Video: wrapped_avframe, p010le(tv, progressive), 320x240
[SAR 1:1 DAR 4:3], q=2-31, 200 kb/s, 25 fps, 25 tbn
Signed-off-by: Haihao Xiang <haihao.xiang@intel.com>
2023-03-08 05:10:48 +00:00
/* User specifies the output format */
if ( vpp - > out_format = = AV_PIX_FMT_NV12 | |
vpp - > out_format = = AV_PIX_FMT_P010 )
out_pix_fmts [ i + + ] = vpp - > out_format ;
else {
out_pix_fmts [ i + + ] = AV_PIX_FMT_NV12 ;
out_pix_fmts [ i + + ] = AV_PIX_FMT_P010 ;
}
out_pix_fmts [ i + + ] = AV_PIX_FMT_QSV ;
out_pix_fmts [ i + + ] = AV_PIX_FMT_NONE ;
2023-01-17 06:20:27 +00:00
return ff_formats_ref ( ff_make_format_list ( out_pix_fmts ) ,
& ctx - > outputs [ 0 ] - > incfg . formats ) ;
}
DEFINE_QSV_FILTER ( vpp , vpp , " VPP " , FILTER_QUERY_FUNC ( vpp_query_formats ) ) ;
2023-01-17 06:20:26 +00:00
# endif
# if CONFIG_SCALE_QSV_FILTER
static const AVOption qsvscale_options [ ] = {
{ " w " , " Output video width(0=input video width, -1=keep input video aspect) " , OFFSET ( ow ) , AV_OPT_TYPE_STRING , { . str = " iw " } , . flags = FLAGS } ,
{ " h " , " Output video height(0=input video height, -1=keep input video aspect) " , OFFSET ( oh ) , AV_OPT_TYPE_STRING , { . str = " ih " } , . flags = FLAGS } ,
{ " format " , " Output pixel format " , OFFSET ( output_format_str ) , AV_OPT_TYPE_STRING , { . str = " same " } , . flags = FLAGS } ,
2022-07-28 03:16:08 +00:00
# if QSV_ONEVPL
{ " mode " , " scaling & format conversion mode (mode compute(3), vd(4) and ve(5) are only available on some platforms) " , OFFSET ( scale_mode ) , AV_OPT_TYPE_INT , { . i64 = 0 } , 0 , 5 , FLAGS , " mode " } ,
# else
{ " mode " , " scaling & format conversion mode " , OFFSET ( scale_mode ) , AV_OPT_TYPE_INT , { . i64 = MFX_SCALING_MODE_DEFAULT } , MFX_SCALING_MODE_DEFAULT , MFX_SCALING_MODE_QUALITY , FLAGS , " mode " } ,
# endif
2023-01-17 06:20:26 +00:00
{ " low_power " , " low power mode " , 0 , AV_OPT_TYPE_CONST , { . i64 = MFX_SCALING_MODE_LOWPOWER } , INT_MIN , INT_MAX , FLAGS , " mode " } ,
{ " hq " , " high quality mode " , 0 , AV_OPT_TYPE_CONST , { . i64 = MFX_SCALING_MODE_QUALITY } , INT_MIN , INT_MAX , FLAGS , " mode " } ,
2022-07-28 03:16:08 +00:00
# if QSV_ONEVPL
{ " compute " , " compute " , 0 , AV_OPT_TYPE_CONST , { . i64 = 3 } , INT_MIN , INT_MAX , FLAGS , " mode " } ,
{ " vd " , " vd " , 0 , AV_OPT_TYPE_CONST , { . i64 = 4 } , INT_MIN , INT_MAX , FLAGS , " mode " } ,
{ " ve " , " ve " , 0 , AV_OPT_TYPE_CONST , { . i64 = 5 } , INT_MIN , INT_MAX , FLAGS , " mode " } ,
# endif
2023-01-17 06:20:26 +00:00
{ NULL } ,
} ;
static av_cold int qsvscale_preinit ( AVFilterContext * ctx )
{
VPPContext * vpp = ctx - > priv ;
vpp_preinit ( ctx ) ;
vpp - > has_passthrough = 0 ;
return 0 ;
}
2023-01-17 06:20:27 +00:00
DEFINE_QSV_FILTER ( qsvscale , scale , " scaling and format conversion " , FILTER_SINGLE_PIXFMT ( AV_PIX_FMT_QSV ) ) ;
2023-01-17 06:20:26 +00:00
# endif
2023-01-30 01:37:19 +00:00
# if CONFIG_DEINTERLACE_QSV_FILTER
static const AVOption qsvdeint_options [ ] = {
{ " mode " , " set deinterlace mode " , OFFSET ( deinterlace ) , AV_OPT_TYPE_INT , { . i64 = MFX_DEINTERLACING_ADVANCED } , MFX_DEINTERLACING_BOB , MFX_DEINTERLACING_ADVANCED , FLAGS , " mode " } ,
{ " bob " , " bob algorithm " , 0 , AV_OPT_TYPE_CONST , { . i64 = MFX_DEINTERLACING_BOB } , MFX_DEINTERLACING_BOB , MFX_DEINTERLACING_ADVANCED , FLAGS , " mode " } ,
{ " advanced " , " Motion adaptive algorithm " , 0 , AV_OPT_TYPE_CONST , { . i64 = MFX_DEINTERLACING_ADVANCED } , MFX_DEINTERLACING_BOB , MFX_DEINTERLACING_ADVANCED , FLAGS , " mode " } ,
{ NULL } ,
} ;
static av_cold int qsvdeint_preinit ( AVFilterContext * ctx )
{
VPPContext * vpp = ctx - > priv ;
vpp_preinit ( ctx ) ;
vpp - > has_passthrough = 0 ;
vpp - > field_rate = 1 ;
return 0 ;
}
DEFINE_QSV_FILTER ( qsvdeint , deinterlace , " deinterlacing " , FILTER_SINGLE_PIXFMT ( AV_PIX_FMT_QSV ) )
# endif