Commit ddea22a6 authored by Mark Thompson's avatar Mark Thompson

avconv: Use codec hardware config to configure hwaccels

Removes specific support for all hwaccels supported by the generic code
(CUVID, DXVA2, D3D11VA, VAAPI and VDPAU).
parent 2117725d
...@@ -1631,44 +1631,77 @@ static void print_sdp(void) ...@@ -1631,44 +1631,77 @@ static void print_sdp(void)
av_freep(&avc); av_freep(&avc);
} }
static const HWAccel *get_hwaccel(enum AVPixelFormat pix_fmt)
{
int i;
for (i = 0; hwaccels[i].name; i++)
if (hwaccels[i].pix_fmt == pix_fmt)
return &hwaccels[i];
return NULL;
}
static enum AVPixelFormat get_format(AVCodecContext *s, const enum AVPixelFormat *pix_fmts) static enum AVPixelFormat get_format(AVCodecContext *s, const enum AVPixelFormat *pix_fmts)
{ {
InputStream *ist = s->opaque; InputStream *ist = s->opaque;
const enum AVPixelFormat *p; const enum AVPixelFormat *p;
int ret; int ret;
for (p = pix_fmts; *p != -1; p++) { for (p = pix_fmts; *p != AV_PIX_FMT_NONE; p++) {
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(*p); const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(*p);
const HWAccel *hwaccel; const AVCodecHWConfig *config = NULL;
int i;
if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL))
break; break;
hwaccel = get_hwaccel(*p); if (ist->hwaccel_id == HWACCEL_GENERIC ||
if (!hwaccel || ist->hwaccel_id == HWACCEL_AUTO) {
(ist->active_hwaccel_id && ist->active_hwaccel_id != hwaccel->id) || for (i = 0;; i++) {
(ist->hwaccel_id != HWACCEL_AUTO && ist->hwaccel_id != hwaccel->id)) config = avcodec_get_hw_config(s->codec, i);
continue; if (!config)
break;
if (!(config->methods &
AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX))
continue;
if (config->pix_fmt == *p)
break;
}
}
if (config) {
if (config->device_type != ist->hwaccel_device_type) {
// Different hwaccel offered, ignore.
continue;
}
ret = hwaccel->init(s); ret = hwaccel_decode_init(s);
if (ret < 0) { if (ret < 0) {
if (ist->hwaccel_id == hwaccel->id) { if (ist->hwaccel_id == HWACCEL_GENERIC) {
av_log(NULL, AV_LOG_FATAL,
"%s hwaccel requested for input stream #%d:%d, "
"but cannot be initialized.\n",
av_hwdevice_get_type_name(config->device_type),
ist->file_index, ist->st->index);
return AV_PIX_FMT_NONE;
}
continue;
}
} else {
const HWAccel *hwaccel = NULL;
int i;
for (i = 0; hwaccels[i].name; i++) {
if (hwaccels[i].pix_fmt == *p) {
hwaccel = &hwaccels[i];
break;
}
}
if (!hwaccel) {
// No hwaccel supporting this pixfmt.
continue;
}
if (hwaccel->id != ist->hwaccel_id) {
// Does not match requested hwaccel.
continue;
}
ret = hwaccel->init(s);
if (ret < 0) {
av_log(NULL, AV_LOG_FATAL, av_log(NULL, AV_LOG_FATAL,
"%s hwaccel requested for input stream #%d:%d, " "%s hwaccel requested for input stream #%d:%d, "
"but cannot be initialized.\n", hwaccel->name, "but cannot be initialized.\n", hwaccel->name,
ist->file_index, ist->st->index); ist->file_index, ist->st->index);
return AV_PIX_FMT_NONE; return AV_PIX_FMT_NONE;
} }
continue;
} }
if (ist->hw_frames_ctx) { if (ist->hw_frames_ctx) {
...@@ -1677,8 +1710,7 @@ static enum AVPixelFormat get_format(AVCodecContext *s, const enum AVPixelFormat ...@@ -1677,8 +1710,7 @@ static enum AVPixelFormat get_format(AVCodecContext *s, const enum AVPixelFormat
return AV_PIX_FMT_NONE; return AV_PIX_FMT_NONE;
} }
ist->active_hwaccel_id = hwaccel->id; ist->hwaccel_pix_fmt = *p;
ist->hwaccel_pix_fmt = *p;
break; break;
} }
......
...@@ -52,13 +52,9 @@ ...@@ -52,13 +52,9 @@
enum HWAccelID { enum HWAccelID {
HWACCEL_NONE = 0, HWACCEL_NONE = 0,
HWACCEL_AUTO, HWACCEL_AUTO,
HWACCEL_VDPAU, HWACCEL_GENERIC,
HWACCEL_DXVA2,
HWACCEL_VDA, HWACCEL_VDA,
HWACCEL_QSV, HWACCEL_QSV,
HWACCEL_VAAPI,
HWACCEL_D3D11VA,
HWACCEL_CUVID,
}; };
typedef struct HWAccel { typedef struct HWAccel {
...@@ -66,7 +62,6 @@ typedef struct HWAccel { ...@@ -66,7 +62,6 @@ typedef struct HWAccel {
int (*init)(AVCodecContext *s); int (*init)(AVCodecContext *s);
enum HWAccelID id; enum HWAccelID id;
enum AVPixelFormat pix_fmt; enum AVPixelFormat pix_fmt;
enum AVHWDeviceType device_type;
} HWAccel; } HWAccel;
typedef struct HWDevice { typedef struct HWDevice {
...@@ -301,11 +296,11 @@ typedef struct InputStream { ...@@ -301,11 +296,11 @@ typedef struct InputStream {
/* hwaccel options */ /* hwaccel options */
enum HWAccelID hwaccel_id; enum HWAccelID hwaccel_id;
enum AVHWDeviceType hwaccel_device_type;
char *hwaccel_device; char *hwaccel_device;
enum AVPixelFormat hwaccel_output_format; enum AVPixelFormat hwaccel_output_format;
/* hwaccel context */ /* hwaccel context */
enum HWAccelID active_hwaccel_id;
void *hwaccel_ctx; void *hwaccel_ctx;
void (*hwaccel_uninit)(AVCodecContext *s); void (*hwaccel_uninit)(AVCodecContext *s);
int (*hwaccel_get_buffer)(AVCodecContext *s, AVFrame *frame, int flags); int (*hwaccel_get_buffer)(AVCodecContext *s, AVFrame *frame, int flags);
......
This diff is collapsed.
...@@ -56,33 +56,11 @@ ...@@ -56,33 +56,11 @@
} }
const HWAccel hwaccels[] = { const HWAccel hwaccels[] = {
#if HAVE_VDPAU_X11
{ "vdpau", hwaccel_decode_init, HWACCEL_VDPAU, AV_PIX_FMT_VDPAU,
AV_HWDEVICE_TYPE_VDPAU },
#endif
#if CONFIG_D3D11VA
{ "d3d11va", hwaccel_decode_init, HWACCEL_D3D11VA, AV_PIX_FMT_D3D11,
AV_HWDEVICE_TYPE_D3D11VA },
#endif
#if CONFIG_DXVA2
{ "dxva2", hwaccel_decode_init, HWACCEL_DXVA2, AV_PIX_FMT_DXVA2_VLD,
AV_HWDEVICE_TYPE_DXVA2 },
#endif
#if CONFIG_VDA #if CONFIG_VDA
{ "vda", vda_init, HWACCEL_VDA, AV_PIX_FMT_VDA, { "vda", vda_init, HWACCEL_VDA, AV_PIX_FMT_VDA },
AV_HWDEVICE_TYPE_NONE },
#endif #endif
#if CONFIG_LIBMFX #if CONFIG_LIBMFX
{ "qsv", qsv_init, HWACCEL_QSV, AV_PIX_FMT_QSV, { "qsv", qsv_init, HWACCEL_QSV, AV_PIX_FMT_QSV },
AV_HWDEVICE_TYPE_NONE },
#endif
#if CONFIG_VAAPI
{ "vaapi", hwaccel_decode_init, HWACCEL_VAAPI, AV_PIX_FMT_VAAPI,
AV_HWDEVICE_TYPE_VAAPI },
#endif
#if CONFIG_CUVID
{ "cuvid", hwaccel_decode_init, HWACCEL_CUVID, AV_PIX_FMT_CUDA,
AV_HWDEVICE_TYPE_CUDA },
#endif #endif
{ 0 }, { 0 },
}; };
...@@ -201,12 +179,15 @@ static double parse_frame_aspect_ratio(const char *arg) ...@@ -201,12 +179,15 @@ static double parse_frame_aspect_ratio(const char *arg)
static int show_hwaccels(void *optctx, const char *opt, const char *arg) static int show_hwaccels(void *optctx, const char *opt, const char *arg)
{ {
enum AVHWDeviceType type = AV_HWDEVICE_TYPE_NONE;
int i; int i;
printf("Supported hardware acceleration:\n"); printf("Supported hardware acceleration:\n");
for (i = 0; hwaccels[i].name; i++) { while ((type = av_hwdevice_iterate_types(type)) !=
AV_HWDEVICE_TYPE_NONE)
printf("%s\n", av_hwdevice_get_type_name(type));
for (i = 0; hwaccels[i].name; i++)
printf("%s\n", hwaccels[i].name); printf("%s\n", hwaccels[i].name);
}
printf("\n"); printf("\n");
return 0; return 0;
} }
...@@ -623,6 +604,7 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic) ...@@ -623,6 +604,7 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
else if (!strcmp(hwaccel, "auto")) else if (!strcmp(hwaccel, "auto"))
ist->hwaccel_id = HWACCEL_AUTO; ist->hwaccel_id = HWACCEL_AUTO;
else { else {
enum AVHWDeviceType type;
int i; int i;
for (i = 0; hwaccels[i].name; i++) { for (i = 0; hwaccels[i].name; i++) {
if (!strcmp(hwaccels[i].name, hwaccel)) { if (!strcmp(hwaccels[i].name, hwaccel)) {
...@@ -631,10 +613,23 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic) ...@@ -631,10 +613,23 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
} }
} }
if (!ist->hwaccel_id) {
type = av_hwdevice_find_type_by_name(hwaccel);
if (type != AV_HWDEVICE_TYPE_NONE) {
ist->hwaccel_id = HWACCEL_GENERIC;
ist->hwaccel_device_type = type;
}
}
if (!ist->hwaccel_id) { if (!ist->hwaccel_id) {
av_log(NULL, AV_LOG_FATAL, "Unrecognized hwaccel: %s.\n", av_log(NULL, AV_LOG_FATAL, "Unrecognized hwaccel: %s.\n",
hwaccel); hwaccel);
av_log(NULL, AV_LOG_FATAL, "Supported hwaccels: "); av_log(NULL, AV_LOG_FATAL, "Supported hwaccels: ");
type = AV_HWDEVICE_TYPE_NONE;
while ((type = av_hwdevice_iterate_types(type)) !=
AV_HWDEVICE_TYPE_NONE)
av_log(NULL, AV_LOG_FATAL, "%s ",
av_hwdevice_get_type_name(type));
for (i = 0; hwaccels[i].name; i++) for (i = 0; hwaccels[i].name; i++)
av_log(NULL, AV_LOG_FATAL, "%s ", hwaccels[i].name); av_log(NULL, AV_LOG_FATAL, "%s ", hwaccels[i].name);
av_log(NULL, AV_LOG_FATAL, "\n"); av_log(NULL, AV_LOG_FATAL, "\n");
......
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