From patchwork Sat Nov 18 18:47:03 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Thompson X-Patchwork-Id: 6169 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.2.161.94 with SMTP id m30csp2081768jah; Sat, 18 Nov 2017 10:47:43 -0800 (PST) X-Google-Smtp-Source: AGs4zMYMCEUCSHk1ApDwKle9x9deOPeATXe0qitCudPdQheBtIx3FmMYCKZBlP+6irsM4Ye34EqW X-Received: by 10.28.146.76 with SMTP id u73mr1815059wmd.28.1511030863527; Sat, 18 Nov 2017 10:47:43 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1511030863; cv=none; d=google.com; s=arc-20160816; b=Ho3UrAfcjnppNL+kone/5LsGwQBJvIGfQ4U9KD70C3IOgWB86tO5WPwTXchl5linum WG2+rTk5R6Kx/lTcq/QryrG0H6gUXxJKu1wuOrHVfaeLiE3TgDeHFOIrMj7sd3JjxO7b esHKFgCKVXCJIuAaBvN4JyfgCvD/qPw+8yBlbeK8AG5Gh6yM8RMzFCCI+11v0kgQyV2i DLLFtOXnBeb/HDbt43Zd9bEFpM8eXNQYqxdFkABGfArAuVlNN9hB2aodvzkWs5bKu3gG IXjuBEJVNDhSeM8IYfy5h3JE+5P6/7z+1RwWx+bOaysyUKaR3sgzG4KJcGNoVGFKRh7A KcGQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:references:in-reply-to:message-id:date :to:from:dkim-signature:delivered-to:arc-authentication-results; bh=32btU7w5lw2j85YkrOyGAtwKN/4t+ehSMAdsIqIjlVE=; b=HnPKVICxGR3HgBFVmedhlT/tE6FM5qFhCSimYlJOaAgjje5MRVYlPLqqX1UErohANv 4hLtRFU7VNY3ouiyisFNuVauQorTi6lrImenWO+3JNMN8CamAcWJuWjS4MO8Joe0yYBf 2HH+5hIRJ4gcmce/gebsykRY49/SsOkN8hzSS3iuP7juDbNXsqgKl1lDdkoAel8Fo8pm vcSD7sdYp+kacN5mvJvA/fVdxDQAl631HUCXSz+HhhLOcF00yfC4TN2Cj21E6NmdVQe3 MN0xu/1rkcY/Fn4BSyK6MVQwTExyv31EPk0tB9y4Cf1Ki+ADRlkdhbH7dt3Ic9DiiLRa n4hg== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@jkqxz-net.20150623.gappssmtp.com header.s=20150623 header.b=J8t/YpzH; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id g131si4646447wma.17.2017.11.18.10.47.43; Sat, 18 Nov 2017 10:47:43 -0800 (PST) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@jkqxz-net.20150623.gappssmtp.com header.s=20150623 header.b=J8t/YpzH; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id AFB5268A069; Sat, 18 Nov 2017 20:47:12 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wr0-f194.google.com (mail-wr0-f194.google.com [209.85.128.194]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id DB93A689FBC for ; Sat, 18 Nov 2017 20:47:03 +0200 (EET) Received: by mail-wr0-f194.google.com with SMTP id 4so4728116wrt.0 for ; Sat, 18 Nov 2017 10:47:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=jkqxz-net.20150623.gappssmtp.com; s=20150623; h=from:to:subject:date:message-id:in-reply-to:references; bh=hcZMdB3WI/FFE3nFuNmjnLTQEilTeK78aqBnunITlPA=; b=J8t/YpzHp1p20lyNQ73DB7X0GnJ0Vn1Jy7C0wKxD0znfOJCoL0zsLvhAlEIL6qXa4O Qj6ini4ilhKVRWTnytbc3HAMd9Qfqed95UbXAOWH75h6LLqW5WSIpY10MZ217+cJhnN4 dhd/cZtPb6Kd1TAyN5szSG6Fl+jlwDNs2nVbVPTXm6KuiQ4X4NJwkUEwpPZtvTPfCYap b3SKPRTaKTLR+SajrqbL1p7fDyfHMpNJ/NZYZxlobhKCUttM19Igdd5L1XSZtn0KyIEl 0gnCFOnhK7ntsBvWOuUSPFlHWmAwjKVZDu4VdunKkiFEkPUmLTjy2RFh8MOb+mZ0/BFf KOBg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=hcZMdB3WI/FFE3nFuNmjnLTQEilTeK78aqBnunITlPA=; b=ajyynHTxP/A6xrczWu4KLvzL8VrHeVW99J0/wdS+BRHg2F488JjUw+8BFEFONHSeAE K7ZpjP5W8iA8RCoy3/qGoH6F0wMq2fPcWgjKtz+YVLa9Ju+t+08H7I31JWxLYj26e+h8 enxVyXWP4hmZgafWdo7cgYC2CVYCJcBLV4VnxzY2AIvdgun44kR0LvHZJhZiyASUpvjz C6ksCrlyHNbK9tCLYFHmM/SA+53hgmVJ+n5y+AbMUqNDTtPcFbSVUrLJXU4OePcCTDeJ JynVLnyC7NJ/MsTe8Hm5+nwFJU+Vwezk66LEhim2i1JmBbZodUUZeqzuV8x7Eo9i6yQD FvTA== X-Gm-Message-State: AJaThX6fvctjAQyI8bwxIs4E6R9QWfPdI1Jl6eg0jBAlDLE6Sc7CfZgD ei1Mgj5P6HsEt3tkHxItNrkRlulF X-Received: by 10.223.139.149 with SMTP id o21mr7337643wra.87.1511030839685; Sat, 18 Nov 2017 10:47:19 -0800 (PST) Received: from rywe.jkqxz.net (cpc91242-cmbg18-2-0-cust650.5-4.cable.virginm.net. [82.8.130.139]) by smtp.gmail.com with ESMTPSA id 143sm13477360wmj.35.2017.11.18.10.47.18 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 18 Nov 2017 10:47:18 -0800 (PST) From: Mark Thompson To: ffmpeg-devel@ffmpeg.org Date: Sat, 18 Nov 2017 18:47:03 +0000 Message-Id: <20171118184713.11490-3-sw@jkqxz.net> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20171118184713.11490-1-sw@jkqxz.net> References: <20171118184713.11490-1-sw@jkqxz.net> Subject: [FFmpeg-devel] [PATCH 03/13] lavc: Use hardware config information in ff_get_format() X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" This removes the dependency that hardware pixel formats previously had on AVHWAccel instances, meaning only those which actually do something need exist after this patch. Also updates avcodec_default_get_format() to be able to choose hardware formats if either a matching device has been supplied or no additional external configuration is required, and avcodec_get_hw_frames_parameters() to use the hardware config rather than searching the old hwaccel list. The FF_CODEC_CAP_HWACCEL_REQUIRE_CLASS mechanism is deleted because it no longer does anything (the codec already contains the pointers to the matching hwaccels). --- libavcodec/avcodec.h | 7 -- libavcodec/cuviddec.c | 2 - libavcodec/decode.c | 285 +++++++++++++++++++++++++++++++++++--------------- libavcodec/internal.h | 11 +- 4 files changed, 208 insertions(+), 97 deletions(-) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 5bbeb67a0d..fb18f46ea2 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -3652,13 +3652,6 @@ typedef struct AVHWAccel { * that avctx->hwaccel_priv_data is invalid. */ int (*frame_params)(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx); - - /** - * Some hwaccels are ambiguous if only the id and pix_fmt fields are used. - * If non-NULL, the associated AVCodec must have - * FF_CODEC_CAP_HWACCEL_REQUIRE_CLASS set. - */ - const AVClass *decoder_class; } AVHWAccel; /** diff --git a/libavcodec/cuviddec.c b/libavcodec/cuviddec.c index 0e5123304a..346e54e7c6 100644 --- a/libavcodec/cuviddec.c +++ b/libavcodec/cuviddec.c @@ -1120,7 +1120,6 @@ static const AVCodecHWConfigInternal *cuvid_hw_configs[] = { .type = AVMEDIA_TYPE_VIDEO, \ .id = AV_CODEC_ID_##X, \ .pix_fmt = AV_PIX_FMT_CUDA, \ - .decoder_class = &x##_cuvid_class, \ }; \ AVCodec ff_##x##_cuvid_decoder = { \ .name = #x "_cuvid", \ @@ -1135,7 +1134,6 @@ static const AVCodecHWConfigInternal *cuvid_hw_configs[] = { .receive_frame = cuvid_output_frame, \ .flush = cuvid_flush, \ .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING, \ - .caps_internal = FF_CODEC_CAP_HWACCEL_REQUIRE_CLASS, \ .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_CUDA, \ AV_PIX_FMT_NV12, \ AV_PIX_FMT_P010, \ diff --git a/libavcodec/decode.c b/libavcodec/decode.c index a7f1e23fc2..8b2bec1ce9 100644 --- a/libavcodec/decode.c +++ b/libavcodec/decode.c @@ -40,6 +40,7 @@ #include "avcodec.h" #include "bytestream.h" #include "decode.h" +#include "hwaccel.h" #include "internal.h" #include "thread.h" @@ -1077,33 +1078,67 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, return ret; } -static int is_hwaccel_pix_fmt(enum AVPixelFormat pix_fmt) +enum AVPixelFormat avcodec_default_get_format(struct AVCodecContext *avctx, + const enum AVPixelFormat *fmt) { - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); - return desc->flags & AV_PIX_FMT_FLAG_HWACCEL; -} - -enum AVPixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum AVPixelFormat *fmt) -{ - while (*fmt != AV_PIX_FMT_NONE && is_hwaccel_pix_fmt(*fmt)) - ++fmt; - return fmt[0]; -} - -static AVHWAccel *find_hwaccel(AVCodecContext *avctx, - enum AVPixelFormat pix_fmt) -{ - AVHWAccel *hwaccel = NULL; - const AVClass *av_class = - (avctx->codec->caps_internal & FF_CODEC_CAP_HWACCEL_REQUIRE_CLASS) - ? avctx->codec->priv_class : NULL; - - while ((hwaccel = av_hwaccel_next(hwaccel))) { - if (hwaccel->decoder_class == av_class && hwaccel->id == avctx->codec_id - && hwaccel->pix_fmt == pix_fmt) - return hwaccel; + const AVPixFmtDescriptor *desc; + const AVCodecHWConfig *config; + int i, n; + + // If a device was supplied when the codec was opened, assume that the + // user wants to use it. + if (avctx->hw_device_ctx && avctx->codec->hw_configs) { + AVHWDeviceContext *device_ctx = + (AVHWDeviceContext*)avctx->hw_device_ctx->data; + for (i = 0;; i++) { + config = &avctx->codec->hw_configs[i]->public; + if (!config) + break; + if (!(config->methods & + AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX)) + continue; + if (device_ctx->type != config->device_type) + continue; + for (n = 0; fmt[n] != AV_PIX_FMT_NONE; n++) { + if (config->pix_fmt == fmt[n]) + return fmt[n]; + } + } + } + // No device or other setup, so we have to choose from things which + // don't any other external information. + + // If the last element of the list is a software format, choose it + // (this should be best software format if any exist). + for (n = 0; fmt[n] != AV_PIX_FMT_NONE; n++); + desc = av_pix_fmt_desc_get(fmt[n - 1]); + if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) + return fmt[n - 1]; + + // Finally, traverse the list in order and choose the first entry + // with no external dependencies (if there is no hardware configuration + // information available then this just picks the first entry). + for (n = 0; fmt[n] != AV_PIX_FMT_NONE; n++) { + for (i = 0;; i++) { + config = avcodec_get_hw_config(avctx->codec, i); + if (!config) + break; + if (config->pix_fmt == fmt[n]) + break; + } + if (!config) { + // No specific config available, so the decoder must be able + // to handle this format without any additional setup. + return fmt[n]; + } + if (config->methods & AV_CODEC_HW_CONFIG_METHOD_INTERNAL) { + // Usable with only internal setup. + return fmt[n]; + } } - return NULL; + + // Nothing is usable, give up. + return AV_PIX_FMT_NONE; } int ff_decode_get_hw_frames_ctx(AVCodecContext *avctx, @@ -1167,9 +1202,19 @@ int avcodec_get_hw_frames_parameters(AVCodecContext *avctx, AVBufferRef **out_frames_ref) { AVBufferRef *frames_ref = NULL; - AVHWAccel *hwa = find_hwaccel(avctx, hw_pix_fmt); - int ret; + const AVCodecHWConfigInternal *hw_config; + const AVHWAccel *hwa; + int i, ret; + for (i = 0;; i++) { + hw_config = avctx->codec->hw_configs[i]; + if (!hw_config) + return AVERROR(ENOENT); + if (hw_config->public.pix_fmt == hw_pix_fmt) + break; + } + + hwa = hw_config->hwaccel; if (!hwa || !hwa->frame_params) return AVERROR(ENOENT); @@ -1186,59 +1231,73 @@ int avcodec_get_hw_frames_parameters(AVCodecContext *avctx, return ret; } -static int setup_hwaccel(AVCodecContext *avctx, - const enum AVPixelFormat fmt, - const char *name) +static int hwaccel_init(AVCodecContext *avctx, + const AVCodecHWConfigInternal *hw_config) { - AVHWAccel *hwa = find_hwaccel(avctx, fmt); - int ret = 0; - - if (!hwa) { - av_log(avctx, AV_LOG_ERROR, - "Could not find an AVHWAccel for the pixel format: %s\n", - name); - return AVERROR(ENOENT); - } + const AVHWAccel *hwaccel; + int err; - if (hwa->capabilities & AV_HWACCEL_CODEC_CAP_EXPERIMENTAL && + hwaccel = hw_config->hwaccel; + if (hwaccel->capabilities & AV_HWACCEL_CODEC_CAP_EXPERIMENTAL && avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) { av_log(avctx, AV_LOG_WARNING, "Ignoring experimental hwaccel: %s\n", - hwa->name); + hwaccel->name); return AVERROR_PATCHWELCOME; } - if (hwa->priv_data_size) { - avctx->internal->hwaccel_priv_data = av_mallocz(hwa->priv_data_size); + if (hwaccel->priv_data_size) { + avctx->internal->hwaccel_priv_data = + av_mallocz(hwaccel->priv_data_size); if (!avctx->internal->hwaccel_priv_data) return AVERROR(ENOMEM); } - avctx->hwaccel = hwa; - if (hwa->init) { - ret = hwa->init(avctx); - if (ret < 0) { - av_freep(&avctx->internal->hwaccel_priv_data); - avctx->hwaccel = NULL; - return ret; - } + avctx->hwaccel = (AVHWAccel*)hwaccel; + err = hwaccel->init(avctx); + if (err < 0) { + av_log(avctx, AV_LOG_ERROR, "Failed setup for format %s: " + "hwaccel initialisation returned error.\n", + av_get_pix_fmt_name(hw_config->public.pix_fmt)); + av_freep(&avctx->internal->hwaccel_priv_data); + avctx->hwaccel = NULL; + return err; } return 0; } +static void hwaccel_uninit(AVCodecContext *avctx) +{ + if (avctx->hwaccel && avctx->hwaccel->uninit) + avctx->hwaccel->uninit(avctx); + + av_freep(&avctx->internal->hwaccel_priv_data); + + avctx->hwaccel = NULL; + + av_buffer_unref(&avctx->hw_frames_ctx); +} + int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt) { const AVPixFmtDescriptor *desc; enum AVPixelFormat *choices; - enum AVPixelFormat ret; - unsigned n = 0; - - while (fmt[n] != AV_PIX_FMT_NONE) - ++n; - + enum AVPixelFormat ret, user_choice; + const AVCodecHWConfigInternal *hw_config; + const AVCodecHWConfig *config; + int i, n, err; + + // Find end of list. + for (n = 0; fmt[n] != AV_PIX_FMT_NONE; n++); + // Must contain at least one entry. av_assert0(n >= 1); - avctx->sw_pix_fmt = fmt[n - 1]; - av_assert2(!is_hwaccel_pix_fmt(avctx->sw_pix_fmt)); + // If a software format is available, it must be the last entry. + desc = av_pix_fmt_desc_get(fmt[n - 1]); + if (desc->flags & AV_PIX_FMT_FLAG_HWACCEL) { + // No software format is available. + } else { + avctx->sw_pix_fmt = fmt[n - 1]; + } choices = av_malloc_array(n + 1, sizeof(*choices)); if (!choices) @@ -1247,44 +1306,104 @@ int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt) memcpy(choices, fmt, (n + 1) * sizeof(*choices)); for (;;) { - if (avctx->hwaccel && avctx->hwaccel->uninit) - avctx->hwaccel->uninit(avctx); - av_freep(&avctx->internal->hwaccel_priv_data); - avctx->hwaccel = NULL; + // Remove the previous hwaccel, if there was one. + hwaccel_uninit(avctx); - av_buffer_unref(&avctx->hw_frames_ctx); - - ret = avctx->get_format(avctx, choices); + user_choice = avctx->get_format(avctx, choices); + if (user_choice == AV_PIX_FMT_NONE) { + // Explicitly chose nothing, give up. + ret = AV_PIX_FMT_NONE; + break; + } - desc = av_pix_fmt_desc_get(ret); + desc = av_pix_fmt_desc_get(user_choice); if (!desc) { + av_log(avctx, AV_LOG_ERROR, "Invalid format returned by " + "get_format() callback.\n"); ret = AV_PIX_FMT_NONE; break; } + av_log(avctx, AV_LOG_DEBUG, "Format %s chosen by get_format().\n", + desc->name); - if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) + for (i = 0; i < n; i++) { + if (choices[i] == user_choice) + break; + } + if (i == n) { + av_log(avctx, AV_LOG_ERROR, "Invalid return from get_format(): " + "%s not in possible list.\n", desc->name); break; + } - if (avctx->hw_frames_ctx) { - AVHWFramesContext *hw_frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data; - if (hw_frames_ctx->format != ret) { - av_log(avctx, AV_LOG_ERROR, "Format returned from get_buffer() " - "does not match the format of provided AVHWFramesContext\n"); - ret = AV_PIX_FMT_NONE; + for (i = 0;; i++) { + hw_config = avctx->codec->hw_configs[i]; + if (!hw_config) + break; + if (hw_config->public.pix_fmt == user_choice) break; - } } - if (!setup_hwaccel(avctx, ret, desc->name)) + if (!hw_config) { + // No config available, so no extra setup required. + ret = user_choice; break; + } + config = &hw_config->public; + + if (config->methods & + AV_CODEC_HW_CONFIG_METHOD_HW_FRAMES_CTX && + avctx->hw_frames_ctx) { + const AVHWFramesContext *frames_ctx = + (AVHWFramesContext*)avctx->hw_frames_ctx->data; + if (frames_ctx->format != user_choice) { + av_log(avctx, AV_LOG_ERROR, "Invalid setup for format %s: " + "does not match the format of the provided frames " + "context.\n", desc->name); + goto try_again; + } + } else if (config->methods & + AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX && + avctx->hw_device_ctx) { + const AVHWDeviceContext *device_ctx = + (AVHWDeviceContext*)avctx->hw_device_ctx->data; + if (device_ctx->type != config->device_type) { + av_log(avctx, AV_LOG_ERROR, "Invalid setup for format %s: " + "does not match the type of the provided device " + "context.\n", desc->name); + goto try_again; + } + } else if (config->methods & + AV_CODEC_HW_CONFIG_METHOD_INTERNAL) { + // Internal-only setup, no additional configuration. + } else if (config->methods & + AV_CODEC_HW_CONFIG_METHOD_AD_HOC) { + // Some ad-hoc configuration we can't see and can't check. + } else { + av_log(avctx, AV_LOG_ERROR, "Invalid setup for format %s: " + "missing configuration.\n", desc->name); + goto try_again; + } + if (hw_config->hwaccel) { + av_log(avctx, AV_LOG_DEBUG, "Format %s requires hwaccel " + "initialisation.\n", desc->name); + err = hwaccel_init(avctx, hw_config); + if (err < 0) + goto try_again; + } + ret = user_choice; + break; - /* Remove failed hwaccel from choices */ - for (n = 0; choices[n] != ret; n++) - av_assert0(choices[n] != AV_PIX_FMT_NONE); - - do - choices[n] = choices[n + 1]; - while (choices[n++] != AV_PIX_FMT_NONE); + try_again: + av_log(avctx, AV_LOG_DEBUG, "Format %s not usable, retrying " + "get_format() without it.\n", desc->name); + for (i = 0; i < n; i++) { + if (choices[i] == user_choice) + break; + } + for (; i + 1 < n; i++) + choices[i] = choices[i + 1]; + --n; } av_freep(&choices); diff --git a/libavcodec/internal.h b/libavcodec/internal.h index d47ce0e93d..a3d046199b 100644 --- a/libavcodec/internal.h +++ b/libavcodec/internal.h @@ -69,11 +69,6 @@ */ #define FF_CODEC_CAP_SLICE_THREAD_HAS_MF (1 << 5) -/** - * Allow only AVHWAccels which have a matching decoder_class field. - */ -#define FF_CODEC_CAP_HWACCEL_REQUIRE_CLASS (1 << 6) - #ifdef TRACE # define ff_tlog(ctx, ...) av_log(ctx, AV_LOG_TRACE, __VA_ARGS__) #else @@ -378,6 +373,12 @@ int ff_side_data_update_matrix_encoding(AVFrame *frame, * Select the (possibly hardware accelerated) pixel format. * This is a wrapper around AVCodecContext.get_format() and should be used * instead of calling get_format() directly. + * + * The list of pixel formats must contain at least one valid entry, and is + * terminated with AV_PIX_FMT_NONE. If it is possible to decode to software, + * the last entry in the list must be the most accurate software format. + * If it is not possible to decode to software, AVCodecContext.sw_pix_fmt + * must be set before calling this function. */ int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt);