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).
This commit is contained in:
parent
2117725dc5
commit
ddea22a684
@ -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);
|
||||||
|
if (!config)
|
||||||
|
break;
|
||||||
|
if (!(config->methods &
|
||||||
|
AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX))
|
||||||
continue;
|
continue;
|
||||||
|
if (config->pix_fmt == *p)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (config) {
|
||||||
|
if (config->device_type != ist->hwaccel_device_type) {
|
||||||
|
// Different hwaccel offered, ignore.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = hwaccel_decode_init(s);
|
||||||
|
if (ret < 0) {
|
||||||
|
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);
|
ret = hwaccel->init(s);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
if (ist->hwaccel_id == hwaccel->id) {
|
|
||||||
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,7 +1710,6 @@ 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 @@
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
|
|
||||||
/* 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);
|
||||||
|
@ -62,6 +62,31 @@ static HWDevice *hw_device_add(void)
|
|||||||
return hw_devices[nb_hw_devices++];
|
return hw_devices[nb_hw_devices++];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *hw_device_default_name(enum AVHWDeviceType type)
|
||||||
|
{
|
||||||
|
// Make an automatic name of the form "type%d". We arbitrarily
|
||||||
|
// limit at 1000 anonymous devices of the same type - there is
|
||||||
|
// probably something else very wrong if you get to this limit.
|
||||||
|
const char *type_name = av_hwdevice_get_type_name(type);
|
||||||
|
char *name;
|
||||||
|
size_t index_pos;
|
||||||
|
int index, index_limit = 1000;
|
||||||
|
index_pos = strlen(type_name);
|
||||||
|
name = av_malloc(index_pos + 4);
|
||||||
|
if (!name)
|
||||||
|
return NULL;
|
||||||
|
for (index = 0; index < index_limit; index++) {
|
||||||
|
snprintf(name, index_pos + 4, "%s%d", type_name, index);
|
||||||
|
if (!hw_device_get_by_name(name))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (index >= index_limit) {
|
||||||
|
av_freep(&name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
int hw_device_init_from_string(const char *arg, HWDevice **dev_out)
|
int hw_device_init_from_string(const char *arg, HWDevice **dev_out)
|
||||||
{
|
{
|
||||||
// "type=name:device,key=value,key2=value2"
|
// "type=name:device,key=value,key2=value2"
|
||||||
@ -109,27 +134,11 @@ int hw_device_init_from_string(const char *arg, HWDevice **dev_out)
|
|||||||
|
|
||||||
p += 1 + k;
|
p += 1 + k;
|
||||||
} else {
|
} else {
|
||||||
// Give the device an automatic name of the form "type%d".
|
name = hw_device_default_name(type);
|
||||||
// We arbitrarily limit at 1000 anonymous devices of the same
|
|
||||||
// type - there is probably something else very wrong if you
|
|
||||||
// get to this limit.
|
|
||||||
size_t index_pos;
|
|
||||||
int index, index_limit = 1000;
|
|
||||||
index_pos = strlen(type_name);
|
|
||||||
name = av_malloc(index_pos + 4);
|
|
||||||
if (!name) {
|
if (!name) {
|
||||||
err = AVERROR(ENOMEM);
|
err = AVERROR(ENOMEM);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
for (index = 0; index < index_limit; index++) {
|
|
||||||
snprintf(name, index_pos + 4, "%s%d", type_name, index);
|
|
||||||
if (!hw_device_get_by_name(name))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (index >= index_limit) {
|
|
||||||
errmsg = "too many devices";
|
|
||||||
goto invalid;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!*p) {
|
if (!*p) {
|
||||||
@ -212,6 +221,49 @@ fail:
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int hw_device_init_from_type(enum AVHWDeviceType type,
|
||||||
|
const char *device,
|
||||||
|
HWDevice **dev_out)
|
||||||
|
{
|
||||||
|
AVBufferRef *device_ref = NULL;
|
||||||
|
HWDevice *dev;
|
||||||
|
char *name;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
name = hw_device_default_name(type);
|
||||||
|
if (!name) {
|
||||||
|
err = AVERROR(ENOMEM);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = av_hwdevice_ctx_create(&device_ref, type, device, NULL, 0);
|
||||||
|
if (err < 0) {
|
||||||
|
av_log(NULL, AV_LOG_ERROR,
|
||||||
|
"Device creation failed: %d.\n", err);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev = hw_device_add();
|
||||||
|
if (!dev) {
|
||||||
|
err = AVERROR(ENOMEM);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev->name = name;
|
||||||
|
dev->type = type;
|
||||||
|
dev->device_ref = device_ref;
|
||||||
|
|
||||||
|
if (dev_out)
|
||||||
|
*dev_out = dev;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
av_freep(&name);
|
||||||
|
av_buffer_unref(&device_ref);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
void hw_device_free_all(void)
|
void hw_device_free_all(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -224,85 +276,130 @@ void hw_device_free_all(void)
|
|||||||
nb_hw_devices = 0;
|
nb_hw_devices = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum AVHWDeviceType hw_device_match_type_by_hwaccel(enum HWAccelID hwaccel_id)
|
static HWDevice *hw_device_match_by_codec(const AVCodec *codec)
|
||||||
{
|
{
|
||||||
|
const AVCodecHWConfig *config;
|
||||||
|
HWDevice *dev;
|
||||||
int i;
|
int i;
|
||||||
if (hwaccel_id == HWACCEL_NONE)
|
for (i = 0;; i++) {
|
||||||
return AV_HWDEVICE_TYPE_NONE;
|
config = avcodec_get_hw_config(codec, i);
|
||||||
for (i = 0; hwaccels[i].name; i++) {
|
if (!config)
|
||||||
if (hwaccels[i].id == hwaccel_id)
|
return NULL;
|
||||||
return hwaccels[i].device_type;
|
if (!(config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX))
|
||||||
|
continue;
|
||||||
|
dev = hw_device_get_by_type(config->device_type);
|
||||||
|
if (dev)
|
||||||
|
return dev;
|
||||||
}
|
}
|
||||||
return AV_HWDEVICE_TYPE_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static enum AVHWDeviceType hw_device_match_type_in_name(const char *codec_name)
|
|
||||||
{
|
|
||||||
const char *type_name;
|
|
||||||
enum AVHWDeviceType type;
|
|
||||||
for (type = av_hwdevice_iterate_types(AV_HWDEVICE_TYPE_NONE);
|
|
||||||
type != AV_HWDEVICE_TYPE_NONE;
|
|
||||||
type = av_hwdevice_iterate_types(type)) {
|
|
||||||
type_name = av_hwdevice_get_type_name(type);
|
|
||||||
if (strstr(codec_name, type_name))
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
return AV_HWDEVICE_TYPE_NONE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int hw_device_setup_for_decode(InputStream *ist)
|
int hw_device_setup_for_decode(InputStream *ist)
|
||||||
{
|
{
|
||||||
|
const AVCodecHWConfig *config;
|
||||||
enum AVHWDeviceType type;
|
enum AVHWDeviceType type;
|
||||||
HWDevice *dev;
|
HWDevice *dev = NULL;
|
||||||
const char *type_name;
|
int err, auto_device = 0;
|
||||||
int err;
|
|
||||||
|
|
||||||
if (ist->hwaccel_device) {
|
if (ist->hwaccel_device) {
|
||||||
dev = hw_device_get_by_name(ist->hwaccel_device);
|
dev = hw_device_get_by_name(ist->hwaccel_device);
|
||||||
if (!dev) {
|
if (!dev) {
|
||||||
char *tmp;
|
if (ist->hwaccel_id == HWACCEL_AUTO) {
|
||||||
size_t len;
|
auto_device = 1;
|
||||||
type = hw_device_match_type_by_hwaccel(ist->hwaccel_id);
|
} else if (ist->hwaccel_id == HWACCEL_GENERIC) {
|
||||||
if (type == AV_HWDEVICE_TYPE_NONE) {
|
type = ist->hwaccel_device_type;
|
||||||
// No match - this isn't necessarily invalid, though,
|
err = hw_device_init_from_type(type, ist->hwaccel_device,
|
||||||
// because an explicit device might not be needed or
|
&dev);
|
||||||
// the hwaccel setup could be handled elsewhere.
|
} else {
|
||||||
|
// This will be dealt with by API-specific initialisation
|
||||||
|
// (using hwaccel_device), so nothing further needed here.
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
type_name = av_hwdevice_get_type_name(type);
|
} else {
|
||||||
len = strlen(type_name) + 1 +
|
if (ist->hwaccel_id == HWACCEL_AUTO) {
|
||||||
strlen(ist->hwaccel_device) + 1;
|
ist->hwaccel_device_type = dev->type;
|
||||||
tmp = av_malloc(len);
|
} else if (ist->hwaccel_device_type != dev->type) {
|
||||||
if (!tmp)
|
av_log(ist->dec_ctx, AV_LOG_ERROR, "Invalid hwaccel device "
|
||||||
return AVERROR(ENOMEM);
|
"specified for decoder: device %s of type %s is not "
|
||||||
snprintf(tmp, len, "%s:%s", type_name, ist->hwaccel_device);
|
"usable with hwaccel %s.\n", dev->name,
|
||||||
err = hw_device_init_from_string(tmp, &dev);
|
av_hwdevice_get_type_name(dev->type),
|
||||||
av_free(tmp);
|
av_hwdevice_get_type_name(ist->hwaccel_device_type));
|
||||||
if (err < 0)
|
return AVERROR(EINVAL);
|
||||||
return err;
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (ist->hwaccel_id != HWACCEL_NONE)
|
if (ist->hwaccel_id == HWACCEL_AUTO) {
|
||||||
type = hw_device_match_type_by_hwaccel(ist->hwaccel_id);
|
auto_device = 1;
|
||||||
else
|
} else if (ist->hwaccel_id == HWACCEL_GENERIC) {
|
||||||
type = hw_device_match_type_in_name(ist->dec->name);
|
type = ist->hwaccel_device_type;
|
||||||
if (type != AV_HWDEVICE_TYPE_NONE) {
|
|
||||||
dev = hw_device_get_by_type(type);
|
dev = hw_device_get_by_type(type);
|
||||||
if (!dev) {
|
if (!dev)
|
||||||
hw_device_init_from_string(av_hwdevice_get_type_name(type),
|
err = hw_device_init_from_type(type, NULL, &dev);
|
||||||
&dev);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// No device required.
|
dev = hw_device_match_by_codec(ist->dec);
|
||||||
|
if (!dev) {
|
||||||
|
// No device for this codec, but not using generic hwaccel
|
||||||
|
// and therefore may well not need one - ignore.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto_device) {
|
||||||
|
int i;
|
||||||
|
if (!avcodec_get_hw_config(ist->dec, 0)) {
|
||||||
|
// Decoder does not support any hardware devices.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
for (i = 0; !dev; i++) {
|
||||||
|
config = avcodec_get_hw_config(ist->dec, i);
|
||||||
|
if (!config)
|
||||||
|
break;
|
||||||
|
type = config->device_type;
|
||||||
|
dev = hw_device_get_by_type(type);
|
||||||
|
if (dev) {
|
||||||
|
av_log(ist->dec_ctx, AV_LOG_INFO, "Using auto "
|
||||||
|
"hwaccel type %s with existing device %s.\n",
|
||||||
|
av_hwdevice_get_type_name(type), dev->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i = 0; !dev; i++) {
|
||||||
|
config = avcodec_get_hw_config(ist->dec, i);
|
||||||
|
if (!config)
|
||||||
|
break;
|
||||||
|
type = config->device_type;
|
||||||
|
// Try to make a new device of this type.
|
||||||
|
err = hw_device_init_from_type(type, ist->hwaccel_device,
|
||||||
|
&dev);
|
||||||
|
if (err < 0) {
|
||||||
|
// Can't make a device of this type.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (ist->hwaccel_device) {
|
||||||
|
av_log(ist->dec_ctx, AV_LOG_INFO, "Using auto "
|
||||||
|
"hwaccel type %s with new device created "
|
||||||
|
"from %s.\n", av_hwdevice_get_type_name(type),
|
||||||
|
ist->hwaccel_device);
|
||||||
|
} else {
|
||||||
|
av_log(ist->dec_ctx, AV_LOG_INFO, "Using auto "
|
||||||
|
"hwaccel type %s with new default device.\n",
|
||||||
|
av_hwdevice_get_type_name(type));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (dev) {
|
||||||
|
ist->hwaccel_device_type = type;
|
||||||
|
} else {
|
||||||
|
av_log(ist->dec_ctx, AV_LOG_INFO, "Auto hwaccel "
|
||||||
|
"disabled: no device found.\n");
|
||||||
|
ist->hwaccel_id = HWACCEL_NONE;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dev) {
|
if (!dev) {
|
||||||
av_log(ist->dec_ctx, AV_LOG_WARNING, "No device available "
|
av_log(ist->dec_ctx, AV_LOG_ERROR, "No device available "
|
||||||
"for decoder (device type %s for codec %s).\n",
|
"for decoder: device type %s needed for codec %s.\n",
|
||||||
av_hwdevice_get_type_name(type), ist->dec->name);
|
av_hwdevice_get_type_name(type), ist->dec->name);
|
||||||
return 0;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
ist->dec_ctx->hw_device_ctx = av_buffer_ref(dev->device_ref);
|
ist->dec_ctx->hw_device_ctx = av_buffer_ref(dev->device_ref);
|
||||||
@ -314,24 +411,16 @@ int hw_device_setup_for_decode(InputStream *ist)
|
|||||||
|
|
||||||
int hw_device_setup_for_encode(OutputStream *ost)
|
int hw_device_setup_for_encode(OutputStream *ost)
|
||||||
{
|
{
|
||||||
enum AVHWDeviceType type;
|
|
||||||
HWDevice *dev;
|
HWDevice *dev;
|
||||||
|
|
||||||
type = hw_device_match_type_in_name(ost->enc->name);
|
dev = hw_device_match_by_codec(ost->enc);
|
||||||
if (type != AV_HWDEVICE_TYPE_NONE) {
|
if (dev) {
|
||||||
dev = hw_device_get_by_type(type);
|
|
||||||
if (!dev) {
|
|
||||||
av_log(ost->enc_ctx, AV_LOG_WARNING, "No device available "
|
|
||||||
"for encoder (device type %s for codec %s).\n",
|
|
||||||
av_hwdevice_get_type_name(type), ost->enc->name);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
ost->enc_ctx->hw_device_ctx = av_buffer_ref(dev->device_ref);
|
ost->enc_ctx->hw_device_ctx = av_buffer_ref(dev->device_ref);
|
||||||
if (!ost->enc_ctx->hw_device_ctx)
|
if (!ost->enc_ctx->hw_device_ctx)
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
// No device required.
|
// No device required, or no device available.
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user