Commit 5d273d3e authored by Mark Thompson's avatar Mark Thompson Committed by Anton Khirnov

avconv: VAAPI hwcontext initialisation and hwaccel helper

Signed-off-by: 's avatarAnton Khirnov <anton@khirnov.net>
parent ca8c7591
......@@ -86,6 +86,7 @@ OBJS-avconv-$(HAVE_VDPAU_X11) += avconv_vdpau.o
OBJS-avconv-$(HAVE_DXVA2_LIB) += avconv_dxva2.o
OBJS-avconv-$(CONFIG_VDA) += avconv_vda.o
OBJS-avconv-$(CONFIG_LIBMFX) += avconv_qsv.o
OBJS-avconv-$(CONFIG_VAAPI) += avconv_vaapi.o
TESTTOOLS = audiogen videogen rotozoom tiny_psnr base64
HOSTPROGS := $(TESTTOOLS:%=tests/%) doc/print_options
......
......@@ -2736,6 +2736,8 @@ static int transcode(void)
}
}
av_buffer_unref(&hw_device_ctx);
/* finished ! */
ret = 0;
......
......@@ -55,6 +55,7 @@ enum HWAccelID {
HWACCEL_DXVA2,
HWACCEL_VDA,
HWACCEL_QSV,
HWACCEL_VAAPI,
};
typedef struct HWAccel {
......@@ -115,6 +116,8 @@ typedef struct OptionsContext {
int nb_hwaccels;
SpecifierOpt *hwaccel_devices;
int nb_hwaccel_devices;
SpecifierOpt *hwaccel_output_formats;
int nb_hwaccel_output_formats;
SpecifierOpt *autorotate;
int nb_autorotate;
......@@ -261,6 +264,7 @@ typedef struct InputStream {
/* hwaccel options */
enum HWAccelID hwaccel_id;
char *hwaccel_device;
enum AVPixelFormat hwaccel_output_format;
/* hwaccel context */
enum HWAccelID active_hwaccel_id;
......@@ -270,6 +274,7 @@ typedef struct InputStream {
int (*hwaccel_retrieve_data)(AVCodecContext *s, AVFrame *frame);
enum AVPixelFormat hwaccel_pix_fmt;
enum AVPixelFormat hwaccel_retrieved_pix_fmt;
AVBufferRef *hw_frames_ctx;
/* stats */
// combined size of all the packets read
......@@ -428,6 +433,8 @@ extern const AVIOInterruptCB int_cb;
extern const OptionDef options[];
extern const HWAccel hwaccels[];
extern int hwaccel_lax_profile_check;
extern AVBufferRef *hw_device_ctx;
void reset_options(OptionsContext *o);
void show_usage(void);
......@@ -451,5 +458,7 @@ int dxva2_init(AVCodecContext *s);
int vda_init(AVCodecContext *s);
int qsv_init(AVCodecContext *s);
int qsv_transcode_init(OutputStream *ost);
int vaapi_decode_init(AVCodecContext *avctx);
int vaapi_device_init(const char *device);
#endif /* AVCONV_H */
......@@ -307,7 +307,7 @@ static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter,
if (ret < 0)
return ret;
if (codec->width || codec->height) {
if (!hw_device_ctx && (codec->width || codec->height)) {
char args[255];
AVFilterContext *filter;
......@@ -513,6 +513,7 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
par->format = ist->hwaccel_retrieve_data ?
ist->hwaccel_retrieved_pix_fmt : ist->dec_ctx->pix_fmt;
par->time_base = tb;
par->hw_frames_ctx = ist->hw_frames_ctx;
ret = av_buffersrc_parameters_set(ifilter->filter, par);
av_freep(&par);
......@@ -719,6 +720,12 @@ int configure_filtergraph(FilterGraph *fg)
if ((ret = avfilter_graph_parse2(fg->graph, graph_desc, &inputs, &outputs)) < 0)
return ret;
if (hw_device_ctx) {
for (i = 0; i < fg->graph->nb_filters; i++) {
fg->graph->filters[i]->hw_device_ctx = av_buffer_ref(hw_device_ctx);
}
}
if (simple && (!inputs || inputs->next || !outputs || outputs->next)) {
av_log(NULL, AV_LOG_ERROR, "Simple filtergraph '%s' does not have "
"exactly one input and output.\n", graph_desc);
......
......@@ -67,9 +67,14 @@ const HWAccel hwaccels[] = {
#endif
#if CONFIG_LIBMFX
{ "qsv", qsv_init, HWACCEL_QSV, AV_PIX_FMT_QSV },
#endif
#if CONFIG_VAAPI
{ "vaapi", vaapi_decode_init, HWACCEL_VAAPI, AV_PIX_FMT_VAAPI },
#endif
{ 0 },
};
int hwaccel_lax_profile_check = 0;
AVBufferRef *hw_device_ctx;
char *vstats_filename;
......@@ -321,6 +326,17 @@ static int opt_attach(void *optctx, const char *opt, const char *arg)
return 0;
}
#if CONFIG_VAAPI
static int opt_vaapi_device(void *optctx, const char *opt, const char *arg)
{
int err;
err = vaapi_device_init(arg);
if (err < 0)
exit_program(1);
return 0;
}
#endif
/**
* Parse a metadata specifier passed as 'arg' parameter.
* @param arg metadata string to parse
......@@ -488,6 +504,7 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
AVCodecParameters *par = st->codecpar;
InputStream *ist = av_mallocz(sizeof(*ist));
char *framerate = NULL, *hwaccel = NULL, *hwaccel_device = NULL;
char *hwaccel_output_format = NULL;
char *codec_tag = NULL;
char *next;
......@@ -581,6 +598,19 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
if (!ist->hwaccel_device)
exit_program(1);
}
MATCH_PER_STREAM_OPT(hwaccel_output_formats, str,
hwaccel_output_format, ic, st);
if (hwaccel_output_format) {
ist->hwaccel_output_format = av_get_pix_fmt(hwaccel_output_format);
if (ist->hwaccel_output_format == AV_PIX_FMT_NONE) {
av_log(NULL, AV_LOG_FATAL, "Unrecognised hwaccel output "
"format: %s", hwaccel_output_format);
}
} else {
ist->hwaccel_output_format = AV_PIX_FMT_NONE;
}
ist->hwaccel_pix_fmt = AV_PIX_FMT_NONE;
break;
......@@ -2475,11 +2505,17 @@ const OptionDef options[] = {
{ "hwaccel_device", OPT_VIDEO | OPT_STRING | HAS_ARG | OPT_EXPERT |
OPT_SPEC | OPT_INPUT, { .off = OFFSET(hwaccel_devices) },
"select a device for HW acceleration", "devicename" },
{ "hwaccel_output_format", OPT_VIDEO | OPT_STRING | HAS_ARG | OPT_EXPERT |
OPT_SPEC | OPT_INPUT, { .off = OFFSET(hwaccel_output_formats) },
"select output format used with HW accelerated decoding", "format" },
{ "hwaccels", OPT_EXIT, { .func_arg = show_hwaccels },
"show available HW acceleration methods" },
{ "autorotate", HAS_ARG | OPT_BOOL | OPT_SPEC |
OPT_EXPERT | OPT_INPUT, { .off = OFFSET(autorotate) },
"automatically insert correct rotate filters" },
{ "hwaccel_lax_profile_check", OPT_BOOL | OPT_EXPERT, { &hwaccel_lax_profile_check},
"attempt to decode anyway if HW accelerated decoder's supported profiles do not exactly match the stream" },
/* audio options */
{ "aframes", OPT_AUDIO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_audio_frames },
......@@ -2535,5 +2571,10 @@ const OptionDef options[] = {
{ "dcodec", HAS_ARG | OPT_DATA | OPT_PERFILE | OPT_EXPERT | OPT_INPUT | OPT_OUTPUT, { .func_arg = opt_data_codec },
"force data codec ('copy' to copy stream)", "codec" },
#if CONFIG_VAAPI
{ "vaapi_device", HAS_ARG | OPT_EXPERT, { .func_arg = opt_vaapi_device },
"set VAAPI hardware device (DRM path or X11 display name)", "device" },
#endif
{ NULL, },
};
This diff is collapsed.
......@@ -1636,6 +1636,7 @@ HAVE_LIST="
sdl
section_data_rel_ro
threads
vaapi_drm
vaapi_x11
vdpau_x11
xlib
......@@ -4694,10 +4695,15 @@ enabled vaapi &&
check_code cc "va/va.h" "vaCreateSurfaces(0, 0, 0, 0, 0, 0, 0, 0)" ||
disable vaapi
enabled vaapi && enabled xlib &&
if enabled vaapi ; then
enabled xlib &&
check_lib2 "va/va.h va/va_x11.h" vaGetDisplay -lva -lva-x11 &&
enable vaapi_x11
check_lib2 "va/va.h va/va_drm.h" vaGetDisplayDRM -lva -lva-drm &&
enable vaapi_drm
fi
enabled vdpau &&
check_cpp_condition vdpau/vdpau.h "defined VDP_DECODER_PROFILE_MPEG4_PART2_ASP" ||
disable vdpau
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment