mirror of
				https://github.com/nyanmisaka/ffmpeg-rockchip.git
				synced 2025-11-01 04:53:04 +08:00 
			
		
		
		
	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:
		| @@ -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 | |||||||
|                 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"); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Mark Thompson
					Mark Thompson